单击按钮时隐藏弹出按钮(DelegateCommand)

时间:2015-02-26 06:38:05

标签: c# xaml mvvm winrt-xaml windows-8.1

我正在构建一个Windows应用商店应用,我有一个如下所示的弹出窗口: flyout

Flyout功能正常,当我点击"添加"时,我可以添加新地址。 Button。问题是,我希望能够隐藏Flyout。我的DelegateCommand位于ViewModel,因此我没有对实际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的引用,但我还没有能够引用树上的任何其他内容。 &#34;添加&#34; ButtonFlyout的子项,附加到&#34;添加地址&#34; AppBarButton

理想情况下,我可以直接向FlyoutAppBarButton传递引用,这样当我点击&#34;添加&#时,我就可以调用Flyout.Hide() 34; Button`。

我尝试设置x:NameAppBarButton的{​​{1}}并在Flyout中引用它们,如下所示:

CommandParameter

在这两种情况下,我的参数都是CommandParameter="{Binding ElementName=AddAddressFlyout}" 。是否可以使用直接数据绑定来完成此操作,或者我是否必须添加某种null s?

3 个答案:

答案 0 :(得分:7)

也许我错过了你的要求中的微妙之处,但我能够使用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#CODE

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


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

答案 1 :(得分:0)

您可能会发现本文很有用,它演示了如何使用依赖项属性来控制是否打开或关闭。然后,您可以将依赖项属性绑定到视图模型上的属性:https://marcominerva.wordpress.com/2013/07/30/using-windows-8-1-flyout-xaml-control-with-mvvm/

我真的只是在我自己的应用程序中尝试过它并且工作正常。

答案 2 :(得分:0)

我建议使用AttachableProperties。我将发送两个我写的易于使用并实现此目标的文件。第一个附加到Flyout并引用一个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>