3

I want to use a color picker in my wpf application and I saw a nice looking one on this codeproject page. The control works fine until I want to connect the control to a viewmodel. I created a small test program with this viewmodel:

public class ColorViewModel : ViewModelBase
{
    public ColorViewModel()
    {
        LineColor = Brushes.Yellow;
    }

    SolidColorBrush _brushColor;
    public SolidColorBrush LineColor
    {
        get { return _brushColor; }
        set
        {
            _brushColor = value;
            RaisePropertyChanged(() => LineColor);
        }
    }
}

The test program has a textbox and the colorpicker controls:

<StackPanel Orientation="Horizontal">
    <TextBlock Text="Please Select a Color" FontWeight="Bold" Margin="10"
               Foreground="{Binding Path=LineColor, UpdateSourceTrigger=PropertyChanged}"/>
     <vw:ColorPickerControlView x:Name="ForeColorPicker" Margin="10"
               CurrentColor="{Binding Path=LineColor, UpdateSourceTrigger=PropertyChanged }"/>
</StackPanel>

In the loaded event of the main window in my test application I set the viewmodel to the datacontext like this:

 DataContext = new ColorViewModel();

The problem is that I can't seem to bind the LineColor property of the viewmodel to the CurrentColor property of the ColorPickerControlView. The CurrentControl property of the ColorPickerControlView seems to be fine. The constructor looks like this:

public ColorPickerControlView()
{
    this.DataContext = this;
    InitializeComponent();
    CommandBindings.Add(new CommandBinding(SelectColorCommand, SelectColorCommandExecute));
}

In the constructor of the UserControl there is the line this.DataContext = this; I read that is is necessary to bind the dependency properties. Do I override this line when I set my viewmodel to the datacontext and is that why I can't bind to the CurrentColor property? Is there any workaround? Or did I make another mistake?

Robert
  • 924
  • 1
  • 9
  • 20

4 Answers4

8

You are right in thinking that the DataContext=this phrase in the UserControl's constructor preempts if from binding to an external viewmodel. It was disccussed in this question. This is easily remedied however. There is only one DependencyProperty in the UserControl's code behind that the xaml binds to: CurrentColor.

Do this:

  • Add a Name="Root" attribute to the UserControl tag of the UserControl's xaml
  • Change the attribute (of the Border tag) Background="{Binding Path=CurrentColor}" to:

    Background="{Binding ElementName=Root, Path=CurrentColor}"

  • Remove the offending DataContext=this line from the UserControl's constructor!

That should be all that there is to it. I wrote a proof of concept that demonstrates the above. If you like I can post it, but the code above should be all you need.

Community
  • 1
  • 1
Dabblernl
  • 15,831
  • 18
  • 96
  • 148
  • It works! Thank you! I will send a link to this discussion to the guy who created the color picker. – Robert Apr 01 '10 at 06:50
0

Both binding must be clashing the set the value of the property. Try Setting the Mode=OneWay

<StackPanel Orientation="Horizontal">
    <TextBlock Text="Please Select a Color" FontWeight="Bold" Margin="10"
               Foreground="{Binding Path=LineColor, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"/>
     <vw:ColorPickerControlView x:Name="ForeColorPicker" Margin="10"
               CurrentColor="{Binding Path=LineColor, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay }"/>
</StackPanel>
Eduardo Molteni
  • 38,786
  • 23
  • 141
  • 206
0

The line this.DataContext = this isn't really needed since you are replacing the DataContext with an instance of the ViewModel. You also do not need to assign the DataContext on the Loaded event handler. Just set it on the constructor. You can set it after the call to InitializeComponent method.

Michael Detras
  • 211
  • 2
  • 5
  • Actually, he's **not** replacing the DataContext with an instance of the ViewModel, so the binding is relative to the control itself... – Thomas Levesque Mar 31 '10 at 21:16
  • Ok, I got to check his post again. He did say that in the Loaded event handler of the window he did this: DataContext = new ColorViewModel(); Does this mean that it isn't replaced? Is there some reason why it isn't replaced? – Michael Detras Apr 01 '10 at 03:50
  • I think I wasn't clear. the line DataContext = new ColorViewModel() is in my test application, it attaches the viewmodel to the main window. this.DataContext=this; is a line in the constructor of the color picker control. The answer of Dabblernl solved my problem. – Robert Apr 01 '10 at 07:45
  • Ok thanks for clarifying. I guess I did not understood it completely. Anyway, I'm glad you already solved your problem. – Michael Detras Apr 01 '10 at 12:56
0
  1. Remove the line DataContext = this in file ColorPickerControlView.xaml.cs
  2. Change the Binding in ColorPickerControlView.xaml to Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type CustomWPFColorPicker:ColorPickerControlView}}, Path=CurrentColor}"
Ben
  • 2,454
  • 26
  • 32