Question

my problem is that the ItemsSource of a ComboBox in an DataGrid is not binding. My UserControl:

<UserControl x:Class="MyClass"
             x:Name="Root"
             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:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro" 
             mc:Ignorable="d" 
             d:DesignHeight="360" d:DesignWidth="757">

The DataGrid:

  <DataGrid x:Name="Article" 
              AutoGenerateColumns="False"
              SelectionUnit="FullRow" 
              SelectionMode="Single"
              CanUserAddRows="False" 
              CanUserDeleteRows="True"
              Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4"
              Margin="5">
        <DataGrid.Columns>
            <DataGridTemplateColumn Width="*"
                                    Header="Article">
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding FilteredArticle, ElementName=Root}"                                      IsEditable="True" 
                                  cal:Message.Attach="[Event KeyUp] = [Action FindArticlel($source)]" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>

If I don't say ElementName=Root, he tries to bind FilteredArticle in the Article class. If I say ElementName=Root, he says the following at runtime:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=Root'. BindingExpression:Path=FilteredArticle; DataItem=null; target element is 'ComboBox' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')

FilteredArticle is a BindableCollection in my ViewModel. All other bindings are working. What is wrong here? Using the latest stable version of Caliburn.Micro.

Was it helpful?

Solution

Binding to the view via ElementName is usually a bad practice. Mainly because someone that creates an instance of the view can give it a different x:Name and that will break your internal binding.

Plus, the FilteredArticle property is not the property of the view but of the view model which is the data context for the view.

Use relative source for binding in those scenarios

ItemsSource="{Binding DataContext.FilteredArticle, 
                      RelativeSource={RelativeSource FindAncestor, 
                                             AncestorType={x:Type UserControl}}}"

You can use a more specific notation (although, in 99% of cases it's not necessary)

ItemsSource="{Binding DataContext.FilteredArticle, 
                      RelativeSource={RelativeSource FindAncestor, 
                                             AncestorType={x:Type local:MyClass}}}"

Where local is the xmlns for the namespace of MyClass

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top