无法为 DependencyProperty 的 ICommand 设置默认值

Posted

技术标签:

【中文标题】无法为 DependencyProperty 的 ICommand 设置默认值【英文标题】:Can't set default value for ICommand of an DependencyProperty 【发布时间】:2016-03-18 23:17:14 【问题描述】:

我想从任何视图模型调用UserControl 的命令。我尝试在我的视图中绑定到命令,但没有成功。

(我没有足够的声誉来发布图片,所以here is a link to the image representation of my question)

View.xaml

<controls:SafeBox
                Height="30"
                VerticalAlignment="Center"
                HorizontalAlignment="Stretch"
                ShowCapsLockAlert="True"
                ShowCopyCommand = "True"
                CopyCommand="Binding CopyCommandInVM"
                AllowClipboardCommands ="True"
                WaterMark ="Enter your master password"/>

这样我只想以编程方式访问 SafeBox 的 CopyCommand。

ViewModel.cs

#region [Command] CopyCommandInVM
public ICommand CopyCommandInVM

    get
    
        return _copyCommandInVM;
    
    set
    
        CopyCommandInVM = value;
    

private ICommand _copyCommandInVM;

#endregion

这样我就可以像这样在我的视图模型中调用 UserControl 的 CopyCommand:CopyCommandInVM.Execute(null);

UserControl.xaml

#region [Dependency Property] CopyCommand
public static readonly DependencyProperty CopyCommandProperty =
DependencyProperty.Register("CopyCommand",
typeof(ICommand),
typeof(SafeBox),
new FrameworkPropertyMetadata

    DefaultValue= new RelayCommand(new Action<object>(Copy)),
    DefaultUpdateSourceTrigger=UpdateSourceTrigger.PropertyChanged

);

[Bindable(true)]
[Category("Command")]
public ICommand CopyCommand

    get
    
        return (ICommand)GetValue(CopyCommandProperty);
    
    set
    
        this.SetValue(CopyCommandProperty, value);
    


/// <summary>
/// Static field, calls the Copy()
/// </summary>
/// <param name="obj"></param>
private static void Copy(object sender)

    /* Not working:
    var holder = obj as SafeBox; 
    holder.Copy();
    how can I make it work or come up with another solution
    to reach the holder of the dependency property (and call the method belown) */


/// <summary>
/// Copies the content of the SafeBox
/// </summary>
/// <param name="obj"></param>
private void Copy()

    //...

#endregion

我的尝试没有成功,我无法访问 UserControl 中的命令。

在询问之前我已经浏览了互联网,但找不到一个很好的可绑定命令示例(使用默认值)。我不想使用任何 MVMM 库。

提前致谢。

编辑:

这是我的场景:

    我主要使用我的 UserControl 而不绑定到这个 Command 属性。

    ViewModel [不知道这个命令] => View [不知道这个命令] => UserControl [执行该命令的默认值]

    但是对于一种情况,我需要调用这个命令(CopyCommandUserControl 来自另一个 ViewModel。我尝试坚持 MVMM 模式所以我的ViewModel 不应该知道View 但打电话 此命令通过binding 发送给它并调用 BindedToChangeVisibility.Execute();.

    ViewModel [CopyOfCopyCommand.Execute(null)] => View [CopyCommand=Binding CopyOfCopyCommand ] => UserControl [运行CopyCommand(默认值)]

【问题讨论】:

能不能使用null并在构造函数中设置默认值? 嗨,谢谢你的想法。我试过了,但它会破坏绑定。我的意思是,如果我像ChangeVisibilityCommand=Binding AnotherCommandFromVM 那样绑定到这个用户控件的命令,那么 AnotherCommandFromVM 不会接受我在用户控件构造函数上设置的命令。 通过绑定设置命令属性将始终替换任何先前设置的命令。双向绑定以及因此 UpdateSourceTrigger 在这里没有意义。双向绑定没有隐藏的魔力,可以将旧命令和新命令保留在一个属性中。 感谢您的解释,但我仍然感到困惑。我几乎完成了我的第一个 wpf/mvmm 桌面应用程序,尽管我认为我可以做基础知识,但我认为我仍然无法理解系统。我需要一个具有默认值的 ICommand 属性,它可以由另一个 ViewModel 执行(通过绑定到用户控件ICommand 并调用Execute()。更新了问题。 你实际上想做什么?如果可能,请用图说明。 【参考方案1】:

我最近刚刚制作了一个 UserControl 并遇到了同样的问题。我创建了一个 所有 UserControl 相关类等的类库,然后将其添加到主项目中。

为了解决您的问题,我创建了一个自己的命令类,名为 (在我的例子中)DropDownControlCommands,它包含所有 ICommands 的实现。

然后,我将需要在项目中使用的一些事件绑定到 DropDownControl 和控件(在您的情况下为按钮)。

当然,这不是最好的解决方案,但效果很好,而且两者兼而有之 控件具有完全相同的命令/操作。

如果您使用此解决方案,我建议您将您的“DropDownControlCommands”-Class(但它可能会被调用)添加到类库中,该类库也包含您的控件。

这使它看起来更有条理,如果您想在另一个项目中再次使用您的控件,那就太好了。

我希望我能帮上忙。不幸的是,我还没有找到更好的解决方案。

【讨论】:

以上是关于无法为 DependencyProperty 的 ICommand 设置默认值的主要内容,如果未能解决你的问题,请参考以下文章

当 UserControl 有 DataContext 时,UserControl 的 DependencyProperty 为 null

DependencyProperty.Register() 用法?

如何在 DependencyProperty 中传播 PropertyChanged 更改

如何使 Binding 尊重 DependencyProperty 值强制?

可以将UpdateSourceTrigger绑定到DependencyProperty吗?

在 DataTemplate 中使用时,行为 DependencyProperty 不更新 ViewModel