Click here to Skip to main content
15,880,972 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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
Posted
Updated 22-Aug-22 11:21am
v2

1. This is trying to point to a Collection of type Tags on the DataContext of the MainWindow.
XML
<DataGrid.Resources>
    <CollectionViewSource
	x:Key="SelectedTagViewSource"
	Source="{Binding Tags}" />
</DataGrid.Resources>

You have set it to MainWindowViewModel in the code behind. You have no Tags collection in the MainWindowViewModel, so you will see a binding error.

2. This is pointing to MainWindowViewModel.DataEntries[].DataEntries.Tags which does not exist.
XML
<uc:TagSelect 
	InstanceID="9" 
    DataContext="{Binding DataEntries}"
	SelectedTags="{Binding Tags}"/>

3. This is attempting to bind to a Property of a type on the DataGridTemplateColumn that does not exist.
XML
SelectedTags="{Binding Tags, RelativeSource={RelativeSource   AncestorType=uc:DataEntry}}"


The binding your the UserControl in the DataGridTemplateColumn looks okay but I'm unsure out how you implement it and the code for the UserControl is missing. You also do not mention what binding errors that you are seeing, so it is too difficult to identify, from the code provided, what is exactly happening.

Are you seeing anything displayed in any of your UserControls?
 
Share this answer
 
v3
Comments
hardover 10-Aug-22 15:35pm    
Thank you. I see all of your points. So the Tags collection does exist in the viewmodel as a collection object DataEntry in the collection DataEntries. How should I make a reference to that?

Also, the first two TextColumns are using the standard binding reference to properties of DataEntry and working fine.

In most of what I have tried, there is no binding failure noted. I do know that SelectedTags DP is not bound only when the UC is used on the DataGrid. That is why I didn't include the UC code because I felt it would be too much and distracting.

The one thing I keep thinking of is a number of mentions that a DataGridTemplateColumn does not appear in the Visual Tree. I assume this is in reference to using a relative source reference. But I don't know what to do with that info.
Graeme_Grant 10-Aug-22 20:20pm    
Are you wanting the default tags (in the VM) for display in every row, or are you wanting to use them for editing the tags that you have?

You have a StaticResource pointing to the Tags collection in the VM however you are not using it in the DataGrid. Check out my answer to another similar question on how I do it: I need to use different font weight on items of a datagridcombobox WPF[^]
hardover 11-Aug-22 16:48pm    
Tags is a collection in every row of the DataEntries collection. The tags collection is a list of selected tags from a larger domain of alltags. alltags are handled inside the usercontrol. Tags is used to set the selections for the listview of the UC
This question has not resulted in a workable solution. It is likely due to poor problem definition/communication on my part. I am closing it.

I have made another example and question, a better attempt a problem definition/communication. Binding datagrid/datagridrow problem

I appreciate any and all input to that problem.

So I can't close it. So I show this as accepted, but there is NO solution here.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900