我正在构建一个Windows应用商店应用,我有一个如下所示的弹出窗口:
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; Button
是Flyout
的子项,附加到&#34;添加地址&#34; AppBarButton
。
理想情况下,我可以直接向Flyout
或AppBarButton
传递引用,这样当我点击&#34;添加&#时,我就可以调用Flyout.Hide()
34; Button`。
我尝试设置x:Name
和AppBarButton
的{{1}}并在Flyout
中引用它们,如下所示:
CommandParameter
在这两种情况下,我的参数都是CommandParameter="{Binding ElementName=AddAddressFlyout}"
。是否可以使用直接数据绑定来完成此操作,或者我是否必须添加某种null
s?
答案 0 :(得分:7)
也许我错过了你的要求中的微妙之处,但我能够使用x:Name和.Hide()
轻松关闭弹出窗口在<Flyout>
标记中使用x:Name =“MyFlyout”,然后通过执行MyFlyout.Hide()
<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>
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>