Binding DataTemplate controls in DataGridTemplateColumn - wpf

I have bounded DataGrid where Items are ObservableCollection of pairs {Prop1, Prop2}
<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox >
<TextBox.Text>
<Binding Path="Prop1">
</Binding>
</TextBox.Text>
</TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
How to bind TextBox Text property to Prop1? I tried as shown above but its not working (looks like data context of TextBox is set to main window).

I've managed to reproduce the issue in question (I assume that "it's not working" means that the value entered in the TextBox is not pushed to your view-model). I am not sure about the exact reasons, but it seems that in this particular scenario, if you don't explicitly set Binding.UpdateSourceTrigger, it defaults (or at least acts like it) to UpdateSourceTrigger.Explicit. So the solution to this problem is to explicitly set the UpdateSourceTrigger on the binding to either UpdateSourceTrigger.LostFocus or UpdateSourceTrigger.PropertyChanged:
<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Prop1, UpdateSourceTrigger=LostFocus}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>

Related

Editabled ComboBox in DataGrid Foucs Not Work

I have a ComboBox in DataGrid,ComboBox's property IsEditable="True",Mouse one click ComboBox,ComboBox is Focus,I find it's TextBox in ComboBox is Focus,But the row which focused ComboBox in DataGrid is not Focus.
But TextBox in DataGrid is not have this Problem.
<DataGridTemplateColumn Header="测试3" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox x:Name="tb" Text="{Binding Dm2}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="测试4" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox x:Name="cb" IsEditable="True" ItemsSource="{Binding DataContext.DmList,RelativeSource={RelativeSource AncestorType=DataGrid}}" SelectedValue="{Binding Dm2}" SelectedValuePath="Dm" DisplayMemberPath="Dm" Text="{Binding Dm2}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
I puzzle this problem three days,I'can find the way to solve the problem.
A lower answer,but it can solve the problem https://www.cnblogs.com/ZXdeveloper/p/9183568.html

How to Bind DataGridTemplateColumn.ClipboardContentBinding to SelectedItem of a Combobox that placed inside it?

I need to bind DataGridTemplateColumn.ClipboardContentBinding to SelectedItem of a Combobox that placed inside that.In fact I need to bind Combobox.SelectedItem to the current row of DataGrid.I tried the code below but it doesn't work.
<DataGrid ItemsSource="{Binding CommentCollection}">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Description" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox DisplayMemberPath="Name"
ItemsSource="{Binding DataContext.CommentCollection,Source={x:Reference GrdSpecDataContext}}"
SelectedItem="{Binding .,Mode=TwoWay}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Please don't tell me I don't need to put ComboBox here or something like that.It's a simple sample,but I need to know it.

WPF Datagrid TemplateColumn Control Enable and Disable

I have Datagrid with two TemplateColumn.
First column is a Combobox and Second column with Extended IntergerUpDown control
I need to Enable/Disable the IntegerUpDown control based on the Combox box SelectedItem value.
Please help me how to accomplish this. Sample xaml below.
<Grid><DataGrid ItemsSource="{Binding List1}" Name="x1">
<DataGrid.Columns>
<DataGridTemplateColumn Header="ColorTemplate">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding DataContext.List2, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}}"
DisplayMemberPath="Name" SelectedValue="{Binding ColourId}" SelectedValuePath="Id" Tag="{Binding Id}"
HorizontalAlignment="Stretch" x:Name="discussTemplate" VerticalAlignment="Stretch"
/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="UPDown" Width="Auto">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<extToolkit:IntegerUpDown AllowSpin="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="Auto" Minimum="0"
x:Name="updown"
IsEnabled="????" >
</extToolkit:IntegerUpDown>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
This can be easily done with a DataTrigger on your ViewModel ColourId property.
As your SelectedValue property on the ComboBox is already binded, you can have a DataTrigger on your extToolkit:IntegerUpDown control that will set IsEnabled to True/False based on ColourId value on your ViewModel.

WPF Data Binding ComboBox in DataGridTemplateColumn

I have a DataGrid and I want to populate a column that contains a ComboBox with a dynamic ItemsSource of elements, based on the row. I have the combo box display correctly, and the correct list of elements are populated in the list, as pulled in from the AvailableLogFileProcessTypes property, which is a ReadOnlyCollection. However, when the selection is made by the user in the combobox, the LogFileProcessType property is not set to the selection.
Data:
Property LogFileDirectories, IEnumerable<LogFileData>,
LogFileData:
public LogFileProcessType LogFileProcessType{get;set;}
public ReadOnlyCollection<LogFileProcessType> AvailableLogFileProcessTypes { get; set; }
The property currently has a backing field, and the breakpoint in the set property does not get hit, so I know it is localized to the binding setup. What is wrong with my XAML that is preventing the property from being set?
As you can see, I've tried setting both the SelectedValue and SelectedItem in the CellEditingTemplate and the CellTemplate. I am not sure which of these is appropriate.
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Path=LogFileDirectories, UpdateSourceTrigger=PropertyChanged}"
HeadersVisibility="Column" CanUserReorderColumns="False" CanUserAddRows="False" Margin="0,0,0,35" Grid.RowSpan="3">
<DataGrid.Columns>
<DataGridCheckBoxColumn Header="Processed" Binding="{Binding Path=IsProcessingComplete, Mode=OneWay}" Width="70" IsReadOnly="True" />
<DataGridTemplateColumn Header="template">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox SelectedValue="{Binding Path=LogFileProcessType, Mode=TwoWay}"
SelectedItem="{Binding Path=LogFileProcessType, Mode=TwoWay}"
ItemsSource="{Binding Path=AvailableLogFileProcessTypes}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox SelectedValue="{Binding Path=LogFileProcessType, Mode=TwoWay}"
SelectedItem="{Binding Path=LogFileProcessType, Mode=TwoWay}"
ItemsSource="{Binding Path=AvailableLogFileProcessTypes}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
See Damascus response for thought process.
Need to Specify UpdateSourceTrigger on CellTemplate / CelLEditTemplate. This triggers the property change.
<DataGridTemplateColumn Header="template">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox SelectedValue="{Binding Path=LogFileProcessType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Path=AvailableLogFileProcessTypes}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox SelectedValue="{Binding Path=LogFileProcessType, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Path=AvailableLogFileProcessTypes}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Try to add this to your ComboBox :
<ComboBox SelectedValue="{Binding Path=LogFileProcessType, Mode=TwoWay}"
SelectedItem="{Binding Path=LogFileProcessType, Mode=TwoWay}"
ItemsSource="{Binding Path=AvailableLogFileProcessTypes, UpdateSourceTrigger=PropertyChanged}"/>
Therefore, with an UpdateSourceTrigger set to PropertyChanged, each time the object AvailableLogFileProcessTypes will change and call OnPropertyChanged, the ItemsSource will be refreshed.

WPF4 DataGridComboBoxColumn doesn't work

Look how odd is the following scenario:
<DataGrid.Columns>
<!--Doesn't work-->
<DataGridComboBoxColumn
Header="Vendor"
ItemsSource="{Binding Vendors}"
SelectedItemBinding="{Binding Vendor,
UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Contact.Title"/>
<!--Works-->
<DataGridTemplateColumn Header="Vendor">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock DataContext="{Binding Vendor}"
Text="{Binding Contact.Title}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Vendors}"
SelectedItem="{Binding Vendor, UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Contact.Title"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
I posted a connection to Microsft.
Microsoft explained to me, that since the common use of the ItemsSource property of the DataGridComboBoxColumn is to bind it to StaticResource or to any other resource that is not different for each row, it's evaluated with the DataGrid once, not per row, so in order to update the ItemsSource for each row individually, a DataGridTemplateColumn and an inner ComboBox, which this one's ItemsSource does bind per row.

Resources