Windows runtime 将操作绑定到XAML中UserControl的属性
我有一个用户控件,它有一个按钮和按钮要执行的操作的依赖属性。包含控件的页面在XAML中设置操作 MyUserControl.cs 按钮和类型为Windows runtime 将操作绑定到XAML中UserControl的属性,windows-runtime,winrt-xaml,Windows Runtime,Winrt Xaml,我有一个用户控件,它有一个按钮和按钮要执行的操作的依赖属性。包含控件的页面在XAML中设置操作 MyUserControl.cs 按钮和类型为操作的依赖属性按钮操作。单击按钮时,它将执行按钮操作 MainPage.xaml.cs 行动1 行动2 MainPage.xaml 使用ButtonAction=Action1显示MyUserControl的实例 问题:ButtonAction属性不是从XAML分配的 MyUserControl.cs MyUserControl.xaml MainPage
操作
的依赖属性按钮操作
。单击按钮时,它将执行按钮操作
MainPage.xaml.cs
行动1
行动2
MainPage.xaml
使用ButtonAction=Action1显示MyUserControl的实例
问题:ButtonAction属性不是从XAML分配的
MyUserControl.cs
MyUserControl.xaml
MainPage.xaml
在这种情况下,还将调用用户控件中的PropertyChanged回调。(此处理程序仅用于诊断目的。我不知道如何在实践中使用它来支持属性)。问题在于数据绑定。
ButtonAction=“{Binding Action1}”
中的Action1
应该是公共属性,而您将其定义为私有变量
此外,您不能像那样直接在代码隐藏中声明普通属性。您将需要依赖属性,或者更常见的是,在实现INotifyPropertyChanged
的viewmodel中需要公共属性
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));
}
}
}
如果使用第二种方法,我们将需要创建一个viewmodel类,如下所示,并带有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=“{Binding Action1,ElementName=x:name of the MainPage}”MainPage没有数据上下文-但是当在代码中分配操作时,它可以正常工作。我尝试了你的建议(设置页面名称和ElementName),结果没有什么不同。不过还是要谢谢你。这两种解决方案都证实有效。非常有趣的是,INotifyPropertyChanged和DependencyObject在xaml中的数据绑定工作是等效的。DependencyObject解决方案的代码是:“类ViewModel:DependencyObject{public Action Action1{get{return(Action)GetValue(Action1Property);}set{SetValue(Action1Property,value);}”public static readonly dependencProperty Action1Property=dependencProperty.Register(“Action1”、typeof(Action)、typeof(ViewModel)、newpropertyMetadata(null));}`这是正确的。您可能已经知道,如果使用dp,则需要通过向绑定表达式添加ElementName=MyMainPage
来稍微修改xaml。比如ButtonAction=“{Binding Action1,ElementName=MyMainPage}”
我明白了。我认为不应该在vm中定义依赖属性。此外,vm不应该实现DependencyObject。在当前上下文中,应该在MyMainPage.xaml.cst中定义dp Action1,这是一个改进!谢谢在dp解决方案中,我删除了类ViewModel
,将Action1
依赖属性移动到MainPage.xaml.cs中,并将xaml更改为ButtonAction=“{Binding Action1,ElementName=MyMainPage}
。
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<local:MyUserControl x:Name="myUserControl" ButtonAction="{Binding Action1}"/>
</Grid>
private void Page_Loaded(object sender, RoutedEventArgs e) {
this.myUserControl.ButtonAction = Action1;
}
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));
}
}
}
public MainPage()
{
this.InitializeComponent();
var vm = new ViewModel();
vm.Action1 = (() =>
{
Debug.WriteLine("Action1 called");
});
this.DataContext = vm;
}