在 WPF 数据网格、组合框模板列上单击编辑
Posted
技术标签:
【中文标题】在 WPF 数据网格、组合框模板列上单击编辑【英文标题】:Single click edit on WPF datagrid , combobox template column 【发布时间】:2012-05-05 08:11:30 【问题描述】:我有一个包含三列的网格:
-
好记的名字
大陆名称
国家/地区名称
第一列是可编辑的文本框列。第二列是显示大陆列表的组合框。第 3 列是一个组合框,显示基于在第 2 列中选择的大陆的国家列表。我想为这些列实现单击。我尝试了此链接中给出的解决方案 Single click edit in WPF DataGrid
但这仅适用于第一列,而不适用于其他两个 (DataGridTemplateColumn) 列。
这怎么可能。请建议。示例 XAML 和数据描述如下。
<DataGrid Grid.Row="1" VerticalAlignment="Top"
ItemsSource="Binding Path=GeographyData,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged"
Style="StaticResource DataGridStyleNormal">
<DataGrid.Columns>
<DataGridTextColumn Width="*" Header="Friendly name" Binding="Binding Path=FriendlyName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged"/>
<!--FilterDef -->
<DataGridTemplateColumn Width="*"
Header="Continents">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox SelectedValue="Binding ContinentId, Mode=TwoWay"
SelectedValuePath="ID"
DisplayMemberPath="Name"
ItemsSource="Binding Path=DataContext.ContinentsAndCountries,Mode=OneWay,UpdateSourceTrigger=PropertyChanged,RelativeSource=RelativeSource Mode=FindAncestor,AncestorType=x:Type DataGrid"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="StaticResource ContinentCaptionConverter">
<Binding Path="ContinentId"/>
<Binding Path="DataContext.ContinentsAndCountries" RelativeSource="RelativeSource Mode=FindAncestor,AncestorType=x:Type DataGrid"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<!--Level-->
<DataGridTemplateColumn Width="*"
Header="Countries">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox SelectedValue="Binding CountryId, Mode=TwoWay"
SelectedValuePath="ID"
DisplayMemberPath="Name">
<ComboBox.ItemsSource>
<MultiBinding Converter="StaticResource CountryValuesConverter">
<Binding Path="DataContext.ContinentsAndCountries" RelativeSource="RelativeSource Mode=FindAncestor,AncestorType=x:Type DataGrid"/>
<Binding Path="ContinentId"/>
</MultiBinding>
</ComboBox.ItemsSource>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="StaticResource CountryCaptionConverter">
<Binding Path="DataContext.ContinentsAndCountries" RelativeSource="RelativeSource Mode=FindAncestor,AncestorType=x:Type DataGrid"/>
<Binding Path="ContinentId"/>
<Binding Path="CountryId"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
注意:数据“ContinentsAndCountries”是主从数据的可观察集合。
吉里哈【问题讨论】:
也许this answer 对你有帮助。 那就看看Tabbing from cell to cell does not set focus on control吧。 不起作用。我想它与此链接***.com/questions/3426765/… 中的功能相同 我通过设置组合框加载事件来做到这一点 private void Combobox_Loaded(object sender, RoutedEventArgs e) if (sender != null) ComboBox cmb = sender as ComboBox; cmb.IsDropDownOpen = true; 很好。然后将其作为答案发布并接受。 【参考方案1】:我通过设置组合框加载事件来做到这一点
private void DataGridComboboxTemplate_Loaded(object sender, RoutedEventArgs e)
if (sender != null)
ComboBox cmb = sender as ComboBox;
cmb.IsDropDownOpen = true;
【讨论】:
【参考方案2】:对不起他的死灵;我终于想出了如何制作真正的单击 UX。您必须拦截 DataGridCell 的 OnGotFocus 事件,将单元格的模式设置为 IsEditing,然后在 CellEditingTemplate 中拦截 Actor 控件的 Loaded 事件:
<Window.Resources>
<Style
x:Key="AutoEditModeOnClick"
TargetType="x:Type DataGridCell">
<EventSetter Event="GotFocus" Handler="DataGridCell_OnGotFocus" />
</Style>
</Window.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn
CellStyle="StaticResource AutoEditModeOnClick"
Header="Score">
<!-- Example with ComboBox -->
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<!-- Some more XAML -->
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<!-- Some more XAML -->
<ComboBox
DisplayMemberPath="Description"
SelectedValuePath="RecordID"
SelectedValue="Binding Score,
TargetNullValue=0,
UpdateSourceTrigger=PropertyChanged"
ItemsSource="Binding DataContext.ScoreOptions,
RelativeSource=RelativeSource
AncestorType=x:Type DataGrid"
Loaded="Combobox_Loaded"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn
CellStyle="StaticResource AutoEditModeOnClick"
Header="Comment">
<!-- Example with TextBox -->
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<!-- Some more XAML -->
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<!-- Some more XAML -->
<TextBox
Loaded="TextBox_Loaded"
Text="Binding Comment,
UpdateSourceTrigger=LostFocus"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
在您的代码隐藏中,您需要三个处理程序;一个用于单元格,一个用于每种类型的控件(组合框、文本框):
/// <summary>
/// Skips the 'DataGridCell.Focus' step and goes straight into IsEditing
/// </summary>
private void DataGridCell_OnGotFocus(object sender, RoutedEventArgs e)
DataGridCell cell = sender as DataGridCell;
cell.IsEditing = true;
/// <summary>
/// Skips the 'IsEditing' step and goes straight into IsDropDownOpen
/// </summary>
private void Combobox_Loaded(object sender, RoutedEventArgs e)
ComboBox comboBox = sender as ComboBox;
comboBox.IsDropDownOpen = true;
/// <summary>
/// Skips the 'IsEditing' step and goes straight into Focus
/// </summary>
private void TextBox_Loaded(object sender, RoutedEventArgs e)
TextBox textBox = sender as TextBox;
textBox.Focus();
【讨论】:
以上是关于在 WPF 数据网格、组合框模板列上单击编辑的主要内容,如果未能解决你的问题,请参考以下文章
WPF C# 组合框空白 SelectedItem SelectedValue