将Action绑定到XAML中UserControl的属性

时间:2015-02-25 05:43:49

标签: windows-runtime winrt-xaml

我有一个用户控件,它有一个按钮和一个依赖属性,用于执行按钮的操作。包含该控件的页面在XAML中设置操作。

MyUserControl.cs

类型为ButtonAction的Button和依赖项属性Action。单击该按钮时,它将执行ButtonAction

MainPage.xaml.cs中

行动措施1

行动动作2

MainPage.xaml中

使用ButtonAction = Action1

呈现MyUserControl的实例

问题:未从XAML分配ButtonAction属性

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回调。 (此处理程序仅用于诊断目的。我无法在实践中看到它如何用于支持该属性。)

1 个答案:

答案 0 :(得分:4)

问题在于您的数据绑定。当您将Action1定义为私有变量时,ButtonAction="{Binding Action1}"中的INotifyPropertyChanged应该是公共属性

另外,你不能直接在后面的代码中声明一个普通的属性。您将需要依赖属性,或更常见的是 viewmodel 中的公共属性,它实现Action1

如果我们采用第二种方法,我们需要创建一个 viewmodel 类,如下所示,具有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

通过这两项更改,您的{{1}}回调应立即启动。 :)