1

I have a UserControl, it contained bool property A. In main window, which contain that UserControl, I have to enable/disable a button depends on the value of A. I tried to make A as public and binding button like this:

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

And in UserControl, I set PropertyChangedEventHandler for Property A like:

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

It look fine. But I have no idea why it does not work. It seems that I have lack of some implementation to communicate between main window and its usercontrol (because with OnPropertyChanged, all binding inside usercontrol work well).

I have some solution for that are 1. Use Messenger to send a message from Usercontrol with the content is value of A, main control will catch & set value to IsEnabled of button. 2. Make a event & raise it anytime value of A is changed.

Do you have any idea about this problems and how to fix it? Do you think 2 below solutions will work well or you have any other recommendation?

Thanks for reading.

<< Edit >> This issue is solved. It is my mistake when set the datacontext of usercontrol in code-behind and do not recognize that I already set them in datatemplate. --> So, duplication make 2 times initialization of viewmodel of usercontrol. --> somehow, it make the NotifyPropertyChange work incorrectly.

I'm sorry the title of this question is not suitable for this silly mistake. It seems that I went on the right way to solve the question on title. Thanks for your reading & your advices.

kidgu
  • 413
  • 1
  • 8
  • 18

3 Answers3

2

Alternate way to display usercontrol in wpf . Check this StackOverflow discussion here

Alternate for INotifyPropertyChanged : Dependency property for binding.

//usercontrol

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>

Community
  • 1
  • 1
C-va
  • 2,910
  • 4
  • 27
  • 42
1

The binding exressions always use the the DataContext as the base for the evaluation of the binding path. So in your case the DataContext must be the window itself, you could set it in the constructor of the window in the code-behind file:

this.DataContext = this;

Also note that to work your window needs to have a property called MyUserControl.

Another option would be to give the MyUserControl instance that you might have instanciated in XAML a name and then use ElementName in the binding expression:

<Grid>
    <loc:MyUserControl Name="myUserControl" />
    <Button IsEnabled="{Binding A, ElementName=myUserControl}" />
</Grid>
bitbonk
  • 48,890
  • 37
  • 186
  • 278
  • I have to set the datacontext to the viewmodel of windows (i'm using mvvm). I also tried to use ElementName & Path instead of use myUserControl.A, but same phenomenon occurs (no binding error, but nothing occurs when I change value of A) – kidgu Jan 15 '13 at 09:46
1

You need to create an instance of UserControl by declaring an it in resources and set it into datacontext and then you can use it. Try this.

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

<StackPanel DataContext="{StaticResource MyUserControl}">
    <Button IsEnabled="{Binding Path=A}" Content="Test" Height="20" />
</StackPanel>
D J
  • 6,908
  • 13
  • 43
  • 75
  • I initialize this usercontrol in viewmodel. i have just add additional information. Hope it more clear! Thanks for your comment! – kidgu Jan 15 '13 at 10:03