我的 View 包含一个 Button
和一个 UserControl
。 UserControl
还包含一个 Button
。我的 View 中的 Button1 和我的 UserControl
中的 Button2 都应该在 ViewModel 中调用相同的方法。
因此我需要将 RelayCommand
“注入(inject)”(不知道如何调用它)到 UserControl
中。我认为使用依赖属性会很容易,但我无法让它工作。
我尝试了什么:
UserControl
包含一个依赖属性,该属性在包含 UserControl
的 View 的 XAML 代码中设置:
用户控制代码:
public const string LoadDataCommandPropertyName = "LoadDataCommand";
public Action LoadDataCommand
{
get
{
return (Action)GetValue(LoadDataCommandProperty);
}
set
{
SetValue(LoadDataCommandProperty, value);
}
}
public static readonly DependencyProperty LoadDataCommandProperty = DependencyProperty.Register(
LoadDataCommandPropertyName,
typeof(Action),
typeof(GridViewPersistenceController),
new UIPropertyMetadata());
查看Xaml代码:(UserControl中dp的使用)
<customControls:MyUserControl Grid.Column="1"
x:Name="RadGridViewSettingsPersistenceControl"
GridControl="{Binding ElementName=RadGridView}"
LoadDataCommand="{Binding ActionTest}"
/>
UserControl 中的 LoadDataCommand 绑定(bind)到 ViewModel 中的这个属性
private const string ActionTestPropertyName = "ActionTest";
private Action actionTest;
public Action ActionTest
{
get
{
return this.actionTest;
}
set
{
this.RaisePropertyChanging(ActionTestPropertyName);
this.actionTest = value;
this.RaisePropertyChanged(ActionTestPropertyName);
}
}
ActionTest 属性在 ViewModel 的构造函数中初始化
public MyViewModel()
{
this.ActionTest = new Action(this.LoadData);
}
visual studio 输出窗口也给了我一个绑定(bind)错误(我不明白)
System.Windows.Data Error: 40 : BindingExpression path error: 'ActionTest' property not found on 'object' ''MyUserControl' (Name='RadGridViewSettingsPersistenceControl')'. BindingExpression:Path=ActionTest; DataItem='MyUserControl' (Name='RadGridViewSettingsPersistenceControl'); target element is 'MyUserControl' (Name='RadGridViewSettingsPersistenceControl'); target property is 'LoadDataCommand' (type 'Action')
我找到了一个可行的解决方法,但我不喜欢它。我在 View 代码隐藏的 LoadedEvent 中设置了 LoadDataCommand。它看起来很乱,我觉得我错过了一些重要的概念。
//TODO: Dirty coding, fix me
private void MyView_OnLoaded(object sender, RoutedEventArgs e)
{
this.RadGridViewSettingsPersistenceControl.LoadDataCommand = new Action((this.DataContext as MyViewModel).LoadData);
}
问题:
- 如何使用 View 中的 xaml 代码将 ViewModel 中定义的
Command
/Action
传递到 UserControl? - 为什么我当前的绑定(bind)方法不起作用?
- 我是否遗漏了一些基本概念? (我可以通过代表更轻松地实现这一点吗?(我试过..))
最佳答案
从错误中可以明显看出:
'ActionTest' property not found on 'object' ''MyUserControl' (Name='RadGridViewSettingsPersistenceControl')'
绑定(bind)引擎正在控件中搜索属性,而不是在您的 ViewModel 中搜索。 (默认情况下,它在控件的 DataContext 中搜索属性,我怀疑您已经在代码中的某处将控件的 DataContext 设置为自身)
使用 RelativeSource 获取您的 UserControl 的 DataContext,这将是您的 ViewModel。
LoadDataCommand="{Binding DataContext.ActionTest,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=UserControl}}"
此外,不要创建 Action
类型的 DP,而是使用 ICommand
并在您的 ViewModel 中创建 ICommand 并绑定(bind)到它。
关于c# - 将 Action 注入(inject) UserControl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21278781/