自定义UserControl的“IsEnabled”数据绑定无效。

5

我现在遇到一个关于WPF应用程序的问题...

我有一个自定义的UserControl用于编辑组件的详细信息。它应该从未启用开始,只有当用户选择要编辑的组件时才能启用。

问题在于:IsEnabled属性甚至没有改变。

以下是我的代码:

<my:UcComponentEditor Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  
                        IsEnabled="{Binding EditorEnabled}"
                              DataContext="{Binding VmComponent}" />

EditorEnabled是我的ViewModel(VmComponent)中的一个属性,默认情况下为false,当用户选择或创建一个组件时变为true。

仅供参考,我的ViewModel中:

private Boolean _editorEnabled = false;

    public Boolean EditorEnabled
    {
        get { return _editorEnabled; }
        set 
        {
            _editorEnabled = value;
            OnPropertyChanged("EditorEnabled");
        }
    }

当我尝试启动我的应用程序时,UserControl正在启动...已启用。 我在各个地方添加了断点,从一开始EditorEnabled就是false。
我还做了一件非常愚蠢的事情来尝试弄清楚发生了什么:我创建了一个转换器(非常有用-将布尔值转换为布尔值-是吗),在它上面设置了断点,但是代码从未到达过那里。
<my:UcComponentEditor Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  
                        IsEnabled="{Binding EditorEnabled, Converter={StaticResource BoolConverter}}"
                              DataContext="{Binding VmComponent}" />

这可能意味着isEnabled属性从未被设置,因为转换器从未被触发。

你是否看到任何问题?我一周前开始使用WPF,因此可能错过了一些重要的东西...

非常感谢您的时间 :-)


断点会停在 _editorEnabled = value; 这一行吗? - Fun Mun Pieng
VmComponent 是否被正确创建?据我所知,该绑定不会初始化一个新的对象。 - Harry
@Fun Mun Pieng:是的,它经过了setter方法。 @Harry:是的,VmComponent已经创建,并且对于所有其他需求都正常工作,只有这一个没有正常工作。 - Damascus
3个回答

3

为了使绑定正常工作,您需要添加一个 DependencyProperty。 在这里查看更多信息。

后台代码:

public static readonly DependencyProperty EditorEnabledDependencyProperty = DependencyProperty.Register("EditorEnabled", typeof(bool), typeof(UcComponentEditor), new PropertyMetadata(false));

public bool EditorEnabled
{
    get { return (bool)base.GetValue(UcComponentEditor.EditorEnabledDependencyProperty); }
    set { base.SetValue(UcComponentEditor.EditorEnabledDependencyProperty, value); }
}

1
真的值得添加吗?我的意思是,该控件已经自然地具有IsEnabled属性。我认为添加一个与IsEnabled具有相同作用的DependencyProperty会导致糟糕的编码 :-/ - Damascus
是的 - 依赖属性在XAML中被广泛使用 - 请查看我发布的链接以获取更多信息。我已经更新了我的答案并附上了一个示例。 - Josh M.
1
@Josh M.:嘿,它实际上可以使用DependencyProperty来设置IsEnabled属性。然而,我觉得需要添加这样的属性来处理已经存在的东西非常不清晰。无论如何,谢谢你的帮助,我会让这个话题保持开放状态,看看是否有其他人有合理的解释 :) - Damascus
1
依赖属性处理绑定源和绑定目标之间的双向通信。它们负责通知您的控件该值已更改。如果您直接将控件“绑定”到属性,则控件无法知道属性何时/是否已更改。唯一的方法是不断轮询属性的值以查看其是否已更改。依赖属性解决了这个问题,这是实现您发布内容的正确方式。您可能应该多了解一些关于依赖属性的知识,但我很高兴它能帮到您。 - Josh M.
好的,我会从现在开始记住这个,如果你这么说的话,我可能需要进一步了解依赖属性 :) 非常感谢! - Damascus
显示剩余2条评论

2

将您的控件封装在DockPanel中(例如)将消除对DependencyProperty的需求。

然后,您可以简单地使用dockpanel进行绑定,而不是使用自定义控件。将绑定到IsEnabled的变量设置为Dockpanel将自动启用或禁用包含在Dockpanel中的项目。


将UserControl放在一个Border中解决了这个问题。 - undefined

1
我认为问题在于用户控件的DataContext属性上绑定了一个属性。这意味着EditorEnabled属性应该是VmComponent对象中的一个属性。至少这就是我的问题所在。
为了解决这个问题,我指定了一个正确的源来绑定IsEnabled。一旦我这样做了,控件就按预期开始工作了。
希望这能有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接