I have a simple WPF window with a TabItem containing a ComboBox with colors and a custom Canvas drawing a rectangle with that color. In my PaintCanvas I have a DependencyProperty like this:
class PaintCanvas : System.Windows.Controls.Canvas
{
public static readonly DependencyProperty PaintObjectProperty = DependencyProperty.Register(
"PaintObject", typeof(PaintObject), typeof(PaintCanvas), new PropertyMetadata(OnPaintObjectChanged));
public PaintObject PaintObject
{
get { return this.GetValue(PaintObjectProperty) as PaintObject; }
set
{
this.SetValue(PaintObjectProperty, value);
}
}
private static void OnPaintObjectChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
PaintCanvas canvas = (PaintCanvas)d;
// Update stuff
canvas.InvalidateVisual();
}
protected override void OnRender(DrawingContext dc)
{
base.OnRender(dc);
if (PaintObject != null)
{
dc.DrawRectangle(new SolidColorBrush(PaintObject.Color), null, new Rect(0, 0, PaintObject.Width, PaintObject.Height));
}
}
}
The PaintObject dependency property is bound in xaml to its corresponding property in PaintViewModel:
<TabControl>
<TabItem DataContext="{Binding PaintViewModel}">
<StackPanel >
<ComboBox ItemsSource="{Binding Colors}" SelectedItem="{Binding Color}" />
<my:PaintCanvas Width="100" Height="100" PaintObject="{Binding PaintObject}" />
</StackPanel>
</TabItem>
</TabControl>
PaintViewModel is a property in the Window’s ViewModel:
class MainViewModel
{
PaintViewModel paintViewModel;
public MainViewModel()
{
paintViewModel = new PaintViewModel();
}
public PaintViewModel PaintViewModel
{
get { return paintViewModel; }
}
...
}
The actual PaintViewModel:
class PaintViewModel : INotifyPropertyChanged
{
PaintObject paintObject;
ObservableCollection<Color> colors = new ObservableCollection<Color>();
Color currentColor;
public PaintObject PaintObject
{
get { return paintObject; }
set { paintObject = value; RaisePropertyChanged("PaintObject"); }
}
public ObservableCollection<Color> Colors
{
get { return colors; }
}
public Color Color
{
get { return currentColor; }
set {
currentColor = value;
RaisePropertyChanged("Color");
paintObject.Color = currentColor;
RaisePropertyChanged("PaintObject");
}
}
// Constructors and INotifyPropertyChanged stuff...
}
The TabItem seems to be correctly bound to the view model, because the color combobox works as it should. However, although the paint object is updated and RaisePropertyChanged(“PaintObject”) is called, the DependencyProperty in PaintCanvas is never updated. What am I doing wrong here??
I don’t see that you change reference to PaintObject, you cahanged one of the properties of it(Color) and fire as PaintObject is changed, and since it is not, dependency property doesnt refresh
As a solution, you can add Color dependency property in the PaintCanvas, and bind Color to PaintObject.Color in xaml
And if you not forget to call NotifyPropertyChanged of Color property in PaintObject, PaintConvas Color property will be fired to be changed
I see some mess in your design, try to keep things simple