[英]Hide Flyout on button click (DelegateCommand)
我正在構建Windows應用商店應用程序,彈出窗口如下所示:
Flyout
Button
運行正常,當我點擊“添加” 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
按預期獲得對Button
的引用,但無法引用樹上的其他任何內容。 “添加” Button
是Flyout
的子級,附加在“添加地址” AppBarButton
。
理想情況下,我可以直接傳遞對Flyout
的引用,也可以傳遞給AppBarButton
,以便單擊“添加”按鈕時可以調用Flyout.Hide()
。
我嘗試設置AppBarButton
和Flyout
的x:Name
並在CommandParameter
引用它們,如下所示:
CommandParameter="{Binding ElementName=AddAddressFlyout}"
在這兩種情況下,我的參數均為null
。 是否可以使用直接數據綁定來完成此操作,還是我必須添加某種Behavior
?
也許我沒有滿足您的要求,但是我可以使用x:Name和.Hide()輕松關閉彈出窗口。
在<Flyout>
標記中使用x:Name =“ MyFlyout”,然后通過執行MyFlyout.Hide()在C#click事件中將其關閉
<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();
}
}
您可能會發現本文很有用,它演示了如何使用依賴項屬性來控制飛出是打開還是關閉。 然后,您可以將依賴項屬性綁定到視圖模型上的屬性: 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.