将 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
回调现在应该会触发。 :)
我有一个用户控件,它有一个按钮和按钮要执行的操作的依赖项 属性。包含控件的页面在 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
回调现在应该会触发。 :)