C# wpf datagrid在DataGridTemplateColumn不工作的情况下单击编辑
我正在基于解析的csv文件动态创建datagrid列。本质上,我是在遵循这项技术,但是我使用了DataGridTemplateColumn,因为我需要指定一个组合作为编辑控件 我还想进行一次单击编辑,我遵循本文中建议的技术,她将她的组合包装在一个网格中,并使用FocusManager.FocusedElement设置焦点 我在ViewModel中执行此操作,创建combo元素的代码如下所示:C# wpf datagrid在DataGridTemplateColumn不工作的情况下单击编辑,c#,wpf,wpfdatagrid,data-binding,C#,Wpf,Wpfdatagrid,Data Binding,我正在基于解析的csv文件动态创建datagrid列。本质上,我是在遵循这项技术,但是我使用了DataGridTemplateColumn,因为我需要指定一个组合作为编辑控件 我还想进行一次单击编辑,我遵循本文中建议的技术,她将她的组合包装在一个网格中,并使用FocusManager.FocusedElement设置焦点 我在ViewModel中执行此操作,创建combo元素的代码如下所示: private static FrameworkElementFactory CreateComboEl
private static FrameworkElementFactory CreateComboElement(int columnIndex, List<string> fieldNameMappings)
{
//note we create the combo in a grid and use the FocusManager to get focus on 1 click!
//so first the grid
FrameworkElementFactory gridElement = new FrameworkElementFactory(typeof(Grid));
Binding gridBinding = new Binding();
gridBinding.ElementName = "combo";
gridElement.SetValue(System.Windows.Input.FocusManager.FocusedElementProperty, gridBinding);
//now the combo
FrameworkElementFactory cboElement = new FrameworkElementFactory(typeof(ComboBox));
gridElement.AppendChild(cboElement);
//set the ItemsSource on the combo
Binding comboBinding = new Binding();
comboBinding.Source = fieldNameMappings;
cboElement.SetBinding(ComboBox.ItemsSourceProperty, comboBinding);
cboElement.SetValue(ComboBox.NameProperty, "combo");
cboElement.SetValue(ComboBox.IsSynchronizedWithCurrentItemProperty, false);
//now set the binding for the selected vlaue in the combo
Binding selectedBinding = new Binding(string.Format("Properties[{0}].Value", columnIndex));
cboElement.SetBinding(ComboBox.SelectedItemProperty, selectedBinding);
return gridElement;
}
有什么问题,为什么单击不起作用?您必须截获DataGridCell的OnGotFocus事件,将单元格的模式设置为IsEditing,然后截获CellEditingTemplate中actor控件的加载事件:
在代码隐藏中,需要三个处理程序;一个用于单元格,一个用于每种类型的控件(组合框、文本框):
//
///跳过“DataGridCell.Focus”步骤,直接进入iEdit
///
私有void DataGridCell_OnGotFocus(对象发送方,RoutedEventTarget e)
{
DataGridCell=发送方为DataGridCell;
cell.IsEditing=true;
}
///
///跳过“IsEdit”步骤,直接进入IsDropDownOpen
///
已加载私有无效组合框(对象发送方,路由目标)
{
ComboBox ComboBox=发件人作为ComboBox;
comboBox.IsDropDownOpen=true;
}
///
///跳过“iEdit”步骤,直接进入焦点
///
已加载私有无效文本框(对象发送方,路由目标)
{
TextBox TextBox=发送者作为TextBox;
textBox.Focus();
}
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=combo'. BindingExpression:(no path); DataItem=null; target element is 'Grid' (Name=''); target property is 'FocusedElement' (type 'IInputElement')
<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();
}