主窗口如何捕获其包含的Usercontrol中的属性的NotifyPropertyChanged事件

时间:2013-01-15 09:10:46

标签: c# .net wpf mvvm

我有一个UserControl,它包含bool属性A. 在包含UserControl的主窗口中,我必须启用/禁用按钮取决于A的值。 我尝试将A作为公共和绑定按钮,如下所示:

<Button IsEnabled="{Binding MyUserControl.A}"/>

在UserControl中,我为Property A设置PropertyChangedEventHandler,如:

private bool _a;
public bool A
{
    get
    {
         return _a;
    }
         set
    {
         if (_a == value)
             return
         _a = value;
         OnPropertyChanged("A");
    }
}

看起来很好。但我不知道为什么它不起作用。 似乎我在主窗口和它的usercontrol之间缺少一些实现来进行通信(因为使用OnPropertyChanged,usercontrol中的所有绑定都能很好地工作)。

我有一些解决方案  1.使用Messenger从Usercontrol发送消息,其内容值为A,主控制将捕获&amp;将值设置为按钮的IsEnabled。  2.举办活动&amp;任何时候A的值都改变了。

您对此问题及其解决方法有何了解? 您认为以下2个解决方案是否能够正常运行,或者您有其他建议?

感谢您阅读。

&LT;&LT;编辑&gt;&gt; 这个问题解决了。在代码隐藏中设置usercontrol的datacontext并且无法识别我已经在datatemplate中设置它们是我的错误。 - &GT;因此,复制使usercontrol的viewmodel初始化2次。 - &GT;不知何故,它使NotifyPropertyChange工作不正确。

对不起,这个问题的标题不适合这个愚蠢的错误。我似乎以正确的方式解决了标题问题。 感谢您的阅读和阅读你的建议。

3 个答案:

答案 0 :(得分:2)

在wpf中显示usercontrol的替代方法。请查看此StackOverflow讨论here

替代INotifyPropertyChanged:绑定的依赖属性。

//用户控件

public partial class UserControl1 : UserControl
{
   public bool A
    {
        get { return (bool)GetValue(AProperty); }
        set { SetValue(AProperty, value); }
    }

    public static readonly DependencyProperty AProperty =
        DependencyProperty.Register("A", typeof(bool), typeof(UserControl1), new UIPropertyMetadata(false));

    public UserControl1()
    {
        InitializeComponent();
        DataContext = this;
    }
}

}

// Mainwindow.xaml

 <Window x:Class="WpfApplication1.MainWindow"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:src="clr-namespace:WpfApplication1"
      Height="300" Width="300">
    <StackPanel>
      <src:UserControl1 x:Name="myControl" />
      <Button IsEnabled="{Binding A, ElementName=myControl}" />
    </StackPanel>

答案 1 :(得分:1)

绑定展示始终使用DataContext作为评估绑定路径的基础。所以在你的情况下DataContext必须是窗口本身,你可以在代码隐藏文件的窗口的构造函数中设置它:

this.DataContext = this;

另请注意,要使用窗口,需要拥有一个名为MyUserControl的属性。

另一个选择是给你可能在XAML中实例化的MyUserControl实例一个名称,然后在绑定表达式中使用ElementName

<Grid>
    <loc:MyUserControl Name="myUserControl" />
    <Button IsEnabled="{Binding A, ElementName=myUserControl}" />
</Grid>

答案 2 :(得分:1)

您需要通过在资源中声明它并将其设置为datacontext来创建UserControl实例,然后您可以使用它。试试这个。

<Window.Resources>
    <WpfApplication2:UserControl1 x:Key="MyUserControl"/>
</Window.Resources>

<StackPanel DataContext="{StaticResource MyUserControl}">
    <Button IsEnabled="{Binding Path=A}" Content="Test" Height="20" />
</StackPanel>