将Action注入UserControl

Joe*_*oel 4 c# wpf command dependency-properties mvvm

我的观点包含a Button和a UserControl.该UserControl还包含一个Button.我的View中的Button1和我的Button2都UserControl应该在ViewModel中调用相同的方法.

ViewViewModelUserControl

因此我需要'注入'(不知道如何调用它)RelayCommand进入UserControl.我认为依赖属性会很容易,但我无法让它工作.

我尝试了什么:

UserControl包含在包含视图的XAML代码设置一个依赖属性UserControl:

用户控制代码:

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());
Run Code Online (Sandbox Code Playgroud)

查看Xaml代码:(在UserControl中使用dp)

<customControls:MyUserControl Grid.Column="1" 
                              x:Name="RadGridViewSettingsPersistenceControl" 
                              GridControl="{Binding ElementName=RadGridView}"
                              LoadDataCommand="{Binding ActionTest}"
                              />
Run Code Online (Sandbox Code Playgroud)

UserControl中的LoadDataCommand绑定到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);
    }
}
Run Code Online (Sandbox Code Playgroud)

ActionTest属性在ViewModel的构造函数中初始化

public MyViewModel()
        {
            this.ActionTest = new Action(this.LoadData);
        }
Run Code Online (Sandbox Code Playgroud)

visual studio输出窗口也给了我一个绑定错误(我不明白)

System.Windows.Data错误:40:BindingExpression路径错误:'object'''MyUserControl'(Name ='RadGridViewSettingsPersistenceControl')'上找不到'ActionTest'属性.BindingExpression:路径= ActionTest; DataItem ='MyUserControl'(Name ='RadGridViewSettingsPersistenceControl'); target元素是'MyUserControl'(Name ='RadGridViewSettingsPersistenceControl'); target属性是'LoadDataCommand'(类型'Action')

我找到了一个有效的解决方法,但我不喜欢它.我在View codebehind的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);
    }
Run Code Online (Sandbox Code Playgroud)

问题:

  • 如何使用View中的xaml代码将ViewModel中的Command/ Action定义传递给UserControl?
  • 为什么我目前使用绑定的方法不起作用?
  • 我错过了一些基本概念吗?(我可以通过代表更轻松地实现这一目标吗?(我试过......))

Roh*_*ats 5

从错误中可以看出:

在'object'''MyUserControl'(Name ='RadGridViewSettingsPersistenceControl')上找不到'ActionTest'属性

绑定引擎正在搜索控件中的属性,而不是在ViewModel中.(默认情况下,它在DataContext控件中搜索属性,我怀疑你已经在代码中的某个地方设置了控件的DataContext)

使用RelativeSource获取UserControl的DataContext,它将是您的ViewModel.

LoadDataCommand="{Binding DataContext.ActionTest,
                   RelativeSource={RelativeSource Mode=FindAncestor,
                                           AncestorType=UserControl}}"
Run Code Online (Sandbox Code Playgroud)

此外,不是创建类型的DP,而是在ViewModel中Action使用ICommand和创建ICommand并绑定到它.

  • 先生,你为自己赢得了一个绿色的勾号。 (2认同)