1

Following up on my previous question (Change brushes based on ViewModel property)

In my UserControl I have have a DependencyObject. I want to bind that object to a property of my ViewModel. In this case a CarViewModel, property name is Status and returns an enum value.

public partial class CarView : UserControl
{
    public CarStatus Status
    {
        get { return (CarStatus)GetValue(CarStatusProperty); }
        set { SetValue(CarStatusProperty, value); }
    }

    public static readonly DependencyProperty CarStatusProperty =
        DependencyProperty.Register("Status", typeof(CarStatus), typeof(CarView), new PropertyMetadata(OnStatusChanged));

    private static void OnStatusChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        var control = (CarView)obj;
        control.LoadThemeResources((CarStatus)e.NewValue == CarStatus.Sold);
    }

    public void LoadThemeResources(bool isSold)
    {
        // change some brushes
    }
}


<UserControl x:Class="MySolution.Views.CarView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:views="clr-MySolution.Views"
             mc:Ignorable="d"
             views:CarView.Status="{Binding Status}">   
    <UserControl.Resources>
    </UserControl.Resources>
    <Grid>
        <TextBlock Text="{Binding Brand}"FontSize="22" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
<UserControl

Where do I need to specify this binding? In the root of the UserControl it gives an error:

The attachable property 'Status' was not found in type 'CarView'

In my MainWindow I bind the CarView using a ContentControl:

<ContentControl
    Content="{Binding CurrentCar}">
    <ContentControl.Resources>
        <DataTemplate DataType="{x:Type viewmodel:CarViewModel}">
            <views:CarView />
        </DataTemplate>
    </ContentControl.Resources>
</ContentControl>

My ViewModel:

[ImplementPropertyChanged]
public class CarViewModel
{
    public Car Car { get; private set; }

    public CarStatus Status
    {
        get
        {
            if (_sold) return CarStatus.Sold;
            return CarStatus.NotSold;
        }
    }
}
Community
  • 1
  • 1
RvdK
  • 19,580
  • 4
  • 64
  • 107
  • I am pretty at ease with MVVM, but I don't see what you re doing with the ContentControl. Inside the ContentControl there is a DataTemplate working only for CarView (DataType attribute is for selection not instanciation), and the binding with the CurrentCar property should have a DataContext object - that I still don't know how it is provided. If you want to provide your ViewModel with XAML : . But I prefer to do it in C# : shorter and sometimes you have to handle the VM in CS. – Emmanuel DURIN Oct 12 '15 at 09:32

2 Answers2

1

your binding isn't well written. instead of writing views:CarView.Status="{Binding Status}" you should write only Status="{Binding Status}"

Franck Ngako
  • 163
  • 6
  • If I do that I get a different errors: "The property 'Status' was not found in type 'UserControl'" and the error: "The property 'Status' does not exist in XML namespace 'http://schemas.microsoft.com/winfx/2006/xaml/presentation'." – RvdK Oct 12 '15 at 10:00
  • a thing you can do is to inherit from userControl. then define your depency property is your newly defined class. then instead of using an opening tag when defining your control, you'll use a new tag instance of your carView someething like this then the Status property will be available – Franck Ngako Oct 12 '15 at 10:23
0

It seems that your Control is binding to itself.
Status is looked for in CarView.

You should have a line of code in your control CodeBehind like :

this.DataContext = new ViewModelObjectWithStatusPropertyToBindFrom();

Regards

Emmanuel DURIN
  • 4,803
  • 2
  • 28
  • 53
  • I've updated my question, I'm not setting the DataContext in code. I set it in XAML. – RvdK Oct 12 '15 at 08:59
  • Fine, may be you should have shown the code. Does your DataContext object have a Status property ? According to your error message, it really seems the DataContext is the userControl. If you follow MVVM, the DataContext should be a VM object – Emmanuel DURIN Oct 12 '15 at 09:02
  • CurrentCar is an object from type CarViewModel – RvdK Oct 12 '15 at 09:05
  • A user/custom control should not need to set **it's own** `DataContext`. It is the responsibility of the control that **hosts** the control to set the `DataContext`. Otherwise you're control is tied to a specific view model implementation, whereas this should not be the case. – Mike Eason Oct 12 '15 at 11:24
  • Yes you re right Mike. I meant, I prefer to provide the data through C# than XAML – Emmanuel DURIN Oct 12 '15 at 11:48