Chengting
Chengting

Reputation: 355

UserControl's DataContext: set it to viewmodel directly

I have a wpf usercontrol and a correspondent viewmodel (ChamberVm) made for it.

In viewmodel there is a property named 'UnitStatus' But I got binding error:

System.Windows.Data Error: 40 : BindingExpression path error: 'UnitStatus' property not found on 'object' ''String' (HashCode=-1814504727)'. BindingExpression:Path=UnitStatus; DataItem='String' (HashCode=-1814504727); target element is 'VacGram' (Name='sysdgm'); target property is 'UnitStatus' (type 'KeyValuePair`2')

I have noted the mistake might be about DataContext setting in the header part of my control:

             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:dgm="clr-namespace:VacSym;assembly=VacSymDgm"             
             xmlns:v="clr-namespace:VacViews"    
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="400"
             DataContext="ChamberVm">
    <Grid Name="gridMain">
        <Grid.RowDefinitions>
            <RowDefinition Height="0*"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="15"></RowDefinition>
        </Grid.RowDefinitions>
        <DockPanel Grid.Row="1">
            <DockPanel x:Name="pnlDgm" Background="Transparent" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                <dgm:VacGram x:Name="sysdgm" UnitStatus="{Binding UnitStatus}" DiagramFile="{Binding DiagramFile}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
            </DockPanel>

       . . .

I want to know:

1, why this is not correct (?)

    DataContext="ChamberVm"

2, what the 'String' means in the error message:

    ...not found on 'object' ''String'

Ting

Upvotes: 0

Views: 564

Answers (2)

Clemens
Clemens

Reputation: 128013

The assignment

DataContext="ChamberVm"

assigns the string "ChamberVm" to the DataContext property.

In order to assign an instance of the ChamberVm class, you would have to write the following, with an appropriate namespace prefix:

<UserControl ...>
    <UserControl.DataContext>
        <v:ChamberVm/>
    </UserControl.DataContext>
    ...
</UserControl>

In general, you should avoid to explicitly assign the DataContext property at all.

You would instead put the UserControl in a DataTemplate that is applied to e.g. a ContentControl that has a ChamberVm object assigned to its Content property. The DataContext of the UserControl would then be set automatically.

Upvotes: 1

jamesnet214
jamesnet214

Reputation: 1162

Your DataContext is a string "ChamberVm", not an object.

That's why you can't find UnitStatus.

<!-- Just set string in DataContext -->
<Window DataContext="ChamberVm">

</Window>

ChamberVm is string right.
So, of course, there is no UnitStatus (object) in DataContext (string).

And DataContext property is object type.

// DependencyProperty
public object DataContext { get; set; }

// You can put anything in.

It's a mistake that everyone makes often.

Anyway, you use DataContext in two main ways.

(To your liking)

1. DataContext Direct Binding in XAML.

<Window xmlns:vm="clr-namespace:VacViews.ViewModels">
    <Window.DataContext>
        <vm:ChamberVm/>
    </Window.DataContext>
</Window>

You must declare the namespace of your view model at the top first. xmlns:vm="your namespace"

And open DataContext to declare the view model you created. This is to create an instance and assign it to DataContext.

2. Set Create Instance in Behind.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        // Your ViewModel set in DataContext.
        DataContext = new ChamberVm();
    }
}

Creating a 'view model' instance within the constructor block is the most impressive position.

Feel free to let me know if you have any further questions.

Upvotes: 0

Related Questions