簡體   English   中英

單擊按鈕時隱藏彈出按鈕(DelegateCommand)

[英]Hide Flyout on button click (DelegateCommand)

我正在構建Windows應用商店應用程序,彈出窗口如下所示: 飛出去

Flyout Button運行正常,當我點擊“添加” Button時,我可以添加一個新地址。 問題是,我也希望能夠隱藏Flyout 我的DelegateCommandViewModel ,所以我沒有對實際View元素的引用。

我嘗試將DelegateCommand更改為采用參數,如下所示:

public DelegateCommand<object> AddAddressCommand
{
    get { return new DelegateCommand<object>(AddAddress, CanAddAddress); }
}

public void AddAddress(object parameter)
{
    if (_isEditing)
    {
        NewAddress.PayeeId = CurrentPayee.Id;
        _addressRepository.InsertAsync(NewAddress);
    }
    CurrentPayee.Addresses.Add(NewAddress);
    NewAddress = new Address();

    // TODO: hide Flyout
}

在我的XAML中,我嘗試將CommandParameter傳遞給DelegateCommand如下所示:

<Button Content="Add" 
        Command="{Binding AddAddressCommand}"
        CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
        HorizontalAlignment="Center" />

如果我通過{RelativeSource Self}Button按預期獲得對Button的引用,但無法引用樹上的其他任何內容。 “添加” ButtonFlyout的子級,附加在“添加地址” AppBarButton

理想情況下,我可以直接傳遞對Flyout的引用,也可以傳遞給AppBarButton ,以便單擊“添加”按鈕時可以調用Flyout.Hide()

我嘗試設置AppBarButtonFlyoutx:Name並在CommandParameter引用它們,如下所示:

CommandParameter="{Binding ElementName=AddAddressFlyout}"

在這兩種情況下,我的參數均為null 是否可以使用直接數據綁定來完成此操作,還是我必須添加某種Behavior

也許我沒有滿足您的要求,但是我可以使用x:Name和.Hide()輕松關閉彈出窗口。

<Flyout>標記中使用x:Name =“ MyFlyout”,然后通過執行MyFlyout.Hide()在C#click事件中將其關閉

XAML代碼:

<Page.BottomAppBar>
    <CommandBar>
        <AppBarButton Icon="Add">
            <AppBarButton.Flyout>
                <Flyout x:Name="MyFlyout">
                    <StackPanel>
                        <Button HorizontalAlignment="Right" Click="CancelButton_Click" Margin="0,-10,-10,0">
                                <SymbolIcon Symbol="Cancel"/>
                        </Button>
                            <TextBlock>Hello World</TextBlock>
                            <TextBox></TextBox>
                    </StackPanel>
                </Flyout>
            </AppBarButton.Flyout>
        </AppBarButton>
    </CommandBar>
</Page.BottomAppBar>

C#代碼

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }


    private void CancelButton_Click(object sender, RoutedEventArgs e)
    {
        MyFlyout.Hide();
    }
}

您可能會發現本文很有用,它演示了如何使用依賴項屬性來控制飛出是打開還是關閉。 然后,您可以將依賴項屬性綁定到視圖模型上的屬性: https : //marcominerva.wordpress.com/2013/07/30/using-windows-8-1-flyout-xaml-control-with-mvvm/

我實際上只是在我自己的應用程序中嘗試過,並且效果很好。

我建議使用AttachableProperties。 我將發送兩個我編寫的易於使用並實現此目標的文件。 第一個附加到彈出按鈕並引用一個Button。 單擊該按鈕時,它將關閉彈出窗口。

第二個附加到Button並引用Flyout(如果Flyout中的按鈕是數據模板的一部分,則很有用)。 僅在這種情況下,您可以具有多個按鈕,當按下這些按鈕時,它們將關閉彈出按鈕,才會產生相同的效果。

首先,在我的項目中有自定義擴展方法,該示例在示例中使用:

public static class XAMLExtensions
{
    public static T GetParent<T>(this DependencyObject dependencyObject) where T : DependencyObject
    {
        var parentDependencyObject = VisualTreeHelper.GetParent(dependencyObject);

        switch (parentDependencyObject)
        {
            case null:
                return null;
            case T parent:
                return parent;
            default:
                return GetParent<T>(parentDependencyObject);
        }        
    }
}

然后是可附加屬性...可附加屬性

public class FlyoutAttach : DependencyObject
{
    private const string CloseButtonPropertyName = "CloseButton";
    private const string CanCloseFlyoutPropertyName = "CanCloseFlyout";
    private const string ClosedCommandPropertyName = "ClosedCommand";
    private const string ClosedCommandParameterPropertyName = "ClosedCommandParameter";

    public static Button GetCloseButton(Flyout flyout) => (Button)flyout.GetValue(CloseButtonProperty);
    public static void SetCloseButton(Flyout flyout, Button value) => flyout.SetValue(CloseButtonProperty, value);
    public static readonly DependencyProperty CloseButtonProperty =
        DependencyProperty.RegisterAttached(CloseButtonPropertyName,
                                            typeof(Button),
                                            typeof(FlyoutAttach),
                                            new PropertyMetadata(null,
                                            new PropertyChangedCallback((s, e) =>
                                            {
                                                if (s is Flyout flyout && e.NewValue is Button button)
                                                {
                                                    button.Click -= buttonClick;
                                                    button.Click += buttonClick;
                                                }
                                                void buttonClick(object sender, RoutedEventArgs routedEventArgs) => flyout.Hide();
                                            })));


    public static bool GetCanCloseFlyout(Button button) => (bool)button.GetValue(CanCloseFlyoutProperty);
    public static void SetCanCloseFlyout(Button button, bool value) => button.SetValue(CanCloseFlyoutProperty, value);
    public static readonly DependencyProperty CanCloseFlyoutProperty =
        DependencyProperty.RegisterAttached(CanCloseFlyoutPropertyName,
                                            typeof(bool),
                                            typeof(FlyoutAttach),
                                            new PropertyMetadata(false,
                                            new PropertyChangedCallback((s, e) =>
                                            {
                                                if (s is Button button && e.NewValue is bool canCloseFlyout)
                                                {
                                                    button.Click -= buttonClick;
                                                    if (canCloseFlyout) button.Click += buttonClick;
                                                }

                                                void buttonClick(object sender, RoutedEventArgs routedEventArgs)
                                                {
                                                    var flyoutPresenter = button.GetParent<FlyoutPresenter>();
                                                    if (flyoutPresenter?.Parent is Popup popup)
                                                        popup.IsOpen = false;
                                                }
                                            })));


    public static ICommand GetClosedCommand(Flyout flyout) => (ICommand)flyout.GetValue(ClosedCommandProperty);
    public static void SetClosedCommand(Flyout flyout, ICommand value) => flyout.SetValue(ClosedCommandProperty, value);
    public static readonly DependencyProperty ClosedCommandProperty =
        DependencyProperty.RegisterAttached(ClosedCommandPropertyName, 
                                            typeof(ICommand), 
                                            typeof(FlyoutAttach), 
                                            new PropertyMetadata(null,
                                            new PropertyChangedCallback((s, e) =>
                                            {
                                                if (s is Flyout flyout && e.NewValue is ICommand command)
                                                {
                                                    flyout.Closed -= flyoutClosed;
                                                    flyout.Closed += flyoutClosed;

                                                    void flyoutClosed(object sender, object ee)
                                                    {
                                                        var commandParameter = flyout.GetValue(ClosedCommandParameterProperty);
                                                        if (command.CanExecute(commandParameter))
                                                            command.Execute(commandParameter);
                                                    }
                                                }
                                            })));


    public static object GetClosedCommandParameter(Flyout flyout) => flyout.GetValue(ClosedCommandParameterProperty);
    public static void SetClosedCommandParameter(Flyout flyout, object value) => flyout.SetValue(ClosedCommandParameterProperty, value);
    public static readonly DependencyProperty ClosedCommandParameterProperty =
        DependencyProperty.RegisterAttached(ClosedCommandParameterPropertyName, typeof(object), typeof(FlyoutAttach), new PropertyMetadata(null));
}

在視圖中

<Flyout Attachable:FlyoutAttach.CloseButton="{Binding ElementName=button}">
     <Button x:Name="button" />
</Flyout>

要么

<Flyout>
     <Button Attachable:FlyoutAttach.CanCloseFlyout="True" />
</Flyout>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM