将 Action 绑定到 XAML 中 UserControl 的 属性

Bind an Action to a property of a UserControl in XAML

我有一个用户控件,它有一个按钮和按钮要执行的操作的依赖项 属性。包含控件的页面在 XAML.

中设置动作

MyUserControl.cs

一个按钮,以及类型为 Action 的依赖项 属性 ButtonAction。单击按钮时,它会执行 ButtonAction.

MainPage.xaml.cs

操作 Action1

动作动作2

MainPage.xaml

使用 ButtonAction=Action1

呈现 MyUserControl 的实例

问题: ButtonAction 属性 未从 XAML

分配

MyUserControl.cs

    public sealed partial class MyUserControl : UserControl
{

    public Action ButtonAction {
        get { return (Action)GetValue(ButtonActionProperty); }
        set { SetValue(ButtonActionProperty, value); }
    }

    public static readonly DependencyProperty ButtonActionProperty =
        DependencyProperty.Register("ButtonAction", typeof(Action), typeof(MyUserControl), new PropertyMetadata(null,ButtonAction_PropertyChanged));

    private static void ButtonAction_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
        Debug.WriteLine("ButtonAction_PropertyChanged");
        // Is not called!
    }


    public MyUserControl() {
        this.InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e) {
        if (ButtonAction != null) {
            // Never reaches here!
            ButtonAction();
        }
    }
}

MyUserControl.xaml

    <Grid>
    <Button Click="Button_Click">Do The Attached Action!</Button>

</Grid>

MainPage.xaml.cs

    Action Action1 = (
        () => { Debug.WriteLine("Action1 called"); });

    Action Action2 = (() => { Debug.WriteLine("Action2 called"); });

MainPage.xaml

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <local:MyUserControl x:Name="myUserControl" ButtonAction="{Binding Action1}"/>
</Grid>

如果在 MainPage (MainPage.xaml.cs) 的代码隐藏中 工作,我在 Loaded 事件中分配操作。

        private void Page_Loaded(object sender, RoutedEventArgs e) {
        this.myUserControl.ButtonAction = Action1;
    }

在这种情况下,还会调用用户控件中的 PropertyChanged 回调。 (此处理程序仅用于诊断目的。我看不出如何在实践中使用它来支持 属性)。

问题出在您的数据绑定中。 ButtonAction="{Binding Action1}" 中的 Action1 应该是 public 属性 而你将其定义为私有变量。

此外,您不能直接在后面的代码中声明一个普通的属性。您将需要 依赖项 属性,或者更常见的是 public 属性 viewmodel 实现了 INotifyPropertyChanged.

如果我们采用第二种方法,我们将需要创建一个 viewmodel class,如下所示,其中包含 Action1 属性 .请注意 OnPropertyChanged 只是实现 INotifyPropertyChanged.

的标准方式
public class ViewModel : INotifyPropertyChanged
{
    private Action _action1;
    public Action Action1
    {
        get { return _action1; }
        set
        {
            _action1 = value;
            OnPropertyChanged("Action1");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string name)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

然后你只需要将它分配给你主页的DataContext

    public MainPage()
    {
        this.InitializeComponent();

        var vm = new ViewModel();
        vm.Action1 = (() =>
        {
            Debug.WriteLine("Action1 called");
        });

        this.DataContext = vm;
    }

通过这两项更改,您的 ButtonAction 回调现在应该会触发。 :)