从 Flyout XAML 内的按钮访问 Flyout

Posted

技术标签:

【中文标题】从 Flyout XAML 内的按钮访问 Flyout【英文标题】:Access Flyout from button inside Flyout XAML 【发布时间】:2016-08-08 12:15:24 【问题描述】:

我觉得这是一个菜鸟 XAML 问题,但还是这样吧。

我想做的事: 我正在开发一个 Windows Phone 8.1 应用程序,我想向自定义浮出控件添加功能,以便连续两次单击浮出控件中的相同菜单按钮,关闭浮出控件。 示例:用户单击浮出控件中的“转到设置”菜单项。如果用户现在再次单击它,则意味着我们已经在设置菜单中,因此我只想关闭弹出窗口。

问题: 我的问题是,当单击其中的按钮时,我需要某种方法来调用弹出窗口中的代码。由于我正在使用 MVVMCross 和 Xamarin(并且我不想将特定于 windows-phone 的逻辑移动到通用的所有平台视图模型中),因此我没有选择在这里执行任何代码隐藏。

目前尝试过: 我尝试通过制作一个继承自 Button 的自定义按钮来解决此问题。当按钮加载时,一个事件被订阅到它的点击事件。发生这种情况时,我尝试通过递归查看按钮的父级(然后是父级的父级)来获取弹出控件的句柄,直到找到它。 ...这不起作用,因为我从未将 Flyout 作为父级,而是获得了 Flyout-presenter(它不允许我访问我的自定义弹出),所以我无法在这里调用我想要的函数。

我尝试制作一个继承自 Button 的自定义“FlyoutButton”。这个按钮有一个可以在 XAML 中设置的 Flyout 的 DependencyProperty,所​​以我有一个按钮内的 Flyout 句柄。 然而,当我尝试这样做时,我只得到异常“System.Void 不能从 C# 中使用”,我真的不知道为什么会这样。下面是我的代码的外观。

我的代码: XAML sn-p:

<Button.Flyout>
   <controls:MainMenuFlyout x:Name="test"
      <Grid.RowDefinitions>
         <RowDefinition Height="*"/>
         <RowDefinition Height="*"/>
         <RowDefinition Height="*"/>
      </Grid.RowDefinitions>
      <controls:MainMenuButton MainMenuFlyout="Binding ElementName=test" Grid.Row="0"/>
      <controls:MainMenuButton MainMenuFlyout="Binding ElementName=test" Grid.Row="0"/>
      <controls:MainMenuButton MainMenuFlyout="Binding ElementName=test" Grid.Row="0"/>
   <controls:MainMenuFlyout />
<Button.Flyout />

C#:

public class MainMenuButton : Button
    
        public static DependencyProperty MainMenuFlyoutProperty = DependencyProperty.Register("MainMenuFlyout", typeof(MainMenuFlyout), typeof(MainMenuButton), new PropertyMetadata(string.Empty, MainMenuFlyoutPropertyChangedCallback));

        public static void SetMainMenuFlyout(UIElement element, MainMenuFlyout value)
        
            element.SetValue(MainMenuFlyoutProperty, value);
        

        public MainMenuFlyout GetMainMenuFlyout(UIElement element)
        
            return (MainMenuFlyout)element.GetValue(MainMenuFlyoutProperty);
        

        private static void MainMenuFlyoutPropertyChangedCallback(DependencyObject dependencyObject,
            DependencyPropertyChangedEventArgs e)
        
        
    

【问题讨论】:

你的依赖属性声明错误。而不是声明静态 getter 和 setter 方法(就像您对附加属性所做的那样),您应该使用调用 GetValue 和 SetValue 的 getter/setter 声明 public MainMenuFlyout MainMenuFlyout 属性。 此外,string.Empty 是 MainMenuFlyout 类型属性的无效默认值。 非常感谢!您的反馈是正确的,并且更改有效! 【参考方案1】:

依赖属性声明错误。应该看起来像这样,使用常规属性包装器而不是静态 getter 和 setter 方法,并将 null 作为默认属性值,而不是 string.Empty

public static DependencyProperty MainMenuFlyoutProperty =
    DependencyProperty.Register(
        "MainMenuFlyout", typeof(MainMenuFlyout), typeof(MainMenuButton),
        new PropertyMetadata(null, MainMenuFlyoutPropertyChangedCallback));

public MainMenuFlyout MainMenuFlyout

    get  return (MainMenuFlyout)GetValue(MainMenuFlyoutProperty); 
    set  SetValue(MainMenuFlyoutProperty, value); 

【讨论】:

以上是关于从 Flyout XAML 内的按钮访问 Flyout的主要内容,如果未能解决你的问题,请参考以下文章

如何从 xaml 访问 UserControl 内的按钮?

C# XAML Flyout 更改标题背景颜色

UWP Flyout浮动控件

从另一类 Windows 手机访问页面的按钮控件?

切换到其他应用时不会触发 UWP Flyout 的关闭事件

c# - 没有按钮的对话框内的WPF关闭对话框