I can’t make binding work to a UserControl in DataGridTemplateColumn. The UserControl is TagSelect. It works with the first two independent uses in this example. I have confirmed that the DP SelectedTags is not binding when used in the DataGrid.
MainWindow.xaml:
<Window
x:Class="TagSelectTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:TagSelectTest"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:uc="clr-namespace:TagSelectTest"
Title="Test Driver for TagSelect User Control"
Width="800"
Height="650"
WindowStartupLocation="CenterScreen"
Closing="Window_Closing"
mc:Ignorable="d">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="500" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="150" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="500" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label
Grid.Row="0"
Grid.Column="0"
Width="138"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="TagSelect User Control"
FontWeight="Bold" />
<uc:TagSelect
Grid.Row="1"
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Top"
InstanceID="0"
SelectedTags="{Binding SomeTags}" />
<uc:TagSelect
Grid.Row="2"
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Top"
InstanceID="1"
SelectedTags="{Binding OtherTags}" />
</Grid>
<DataGrid
x:Name="TestGrid"
Grid.Row="3"
Grid.Column="0"
Width="430"
AutoGenerateColumns="False"
ItemsSource="{Binding DataEntries}">
<DataGrid.Columns>
<DataGridTextColumn
Width="40"
Binding="{Binding ID}"
Header="ID" />
<DataGridTextColumn
Width="200"
Binding="{Binding Name}"
Header="Name" />
<DataGridTemplateColumn
Width="175"
Header="Tags">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<uc:TagSelect
InstanceID="9"
SelectedTags="{Binding Tags}"
/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
MainWindow.xaml.cs:
namespace TagSelectTest
{
public partial class MainWindow : Window
{
MainWindowViewModel vm;
public MainWindow()
{
vm = new MainWindowViewModel();
DataContext = vm;
InitializeComponent();
}
}
}
MainWindowViewModel.cs:
public class MainWindowViewModel : ViewModelBase
{
private List<Tag>? selTags = new();
public List<Tag> SomeTags
{
get
{
return selTags;
}
set
{
selTags = value;
RaisePropertyChanged();
}
}
private List<Tag>? othTags = new();
public List<Tag> OtherTags
{
get
{
return othTags;
}
set
{
othTags = value;
RaisePropertyChanged();
}
}
private ObservableCollection<DataEntry>? dataEntries;
public ObservableCollection<DataEntry>? DataEntries
{
get { return dataEntries; }
set
{
dataEntries = value;
RaisePropertyChanged();
}
}
public MainWindowViewModel()
{
SomeTags.Add(new Tag(16, "Rebecca", " "));
SomeTags.Add(new Tag(23, "Yukon", " "));
OtherTags.Add(new Tag(15, "NewSys", " "));
OtherTags.Add(new Tag(14, "Marlee", " "));
OtherTags.Add(new Tag(3, "Boogie", " "));
DataEntries = new ObservableCollection<DataEntry>();
DataEntry de = new DataEntry();
de.ID = 0;
de.Name = "first";
de.Tags.Add(new Tag(7, "Envoy", " "));
de.Tags.Add(new Tag(11, "John H", " "));
DataEntries.Add(de);
de = new DataEntry();
de.ID = 1;
de.Name = "second";
de.Tags.Add(new Tag(5, "Christmas Gifts", " "));
de.Tags.Add(new Tag(1, "Accord", " "));
de.Tags.Add(new Tag(3, "Boogie", " "));
de.Tags.Add(new Tag(15, "NewSys", " "));
DataEntries.Add(de);
de = new DataEntry();
de.ID = 2;
de.Name = "third";
de.Tags.Add(new Tag(12, "John O", " "));
de.Tags.Add(new Tag(14, "Marlee", " "));
de.Tags.Add(new Tag(19, "Savings -General", " "));
DataEntries.Add(de);
}
}
I doesn't seem necessary to include the code for TagSelect. I have confirmed that the binding is not working when it is used in the DataGrid.
Can Anyone offer a solution?
What I have tried:
I have tried all of any similar recommendations if have found. Here are some:
1. Use a CollectionViewSource
<DataGrid.Resources>
<CollectionViewSource
x:Key="SelectedTagViewSource"
Source="{Binding Tags}" />
</DataGrid.Resources>
<uc:TagSelect
InstanceID="9"
SelectedTags="{Binding Source={StaticResource SelectedTagViewSource}}"/>
2. referencing DataContext in the Data Template??
<uc:TagSelect
InstanceID="9"
DataContext="{Binding DataEntries}"
SelectedTags="{Binding Tags}"/>
3. using RelativeSource to reference the DataGrid
SelectedTags="{Binding Tags, RelativeSource={RelativeSource AncestorType=uc:DataEntry}}"
And I thought I was beginning to understand this binding thing.
Added this latest try:
<Grid.Resources>
<CollectionViewSource
x:Key="SelectedTagsSource"
Source="{Binding Path=DataEntries.DataEntry.Tags}"/>
</Grid.Resources>
...
<DataTemplate>
<uc:TagSelect
InstanceID="9"
SelectedTags="{Binding Source={StaticResource SelectedTagsSource}}" />
</DataTemplate>
Got this binding failure:
Severity Count Data Context Binding Path Target Target Type Description File Line Project
Error 1 ObservableCollection`1 DataEntry CollectionViewSource.Source Object DataEntry property not found on object of type ObservableCollection`1. \mainwindow.xaml 17 TagSelectTest