我正在根据解析的csv文件动态创建datagrid列。基本上我正在遵循技术here,但是我正在使用DataGridTemplateColumn,因为我需要将组合指定为编辑控件。
我还希望进行单击编辑,并且我遵循本文here by Julie Lerman中建议的技术,该文章将她的组合包装在网格中并使用 FocusManager.FocusedElement 来设定焦点。
我在ViewModel中这样做,创建组合元素的代码如下所示:
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;
}
问题是,单击编辑不起作用,并且在运行时我看到第二次单击后仍然需要调用编辑时出现以下错误:
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')
有什么问题,为什么单击不起作用?
答案 0 :(得分:0)
您必须拦截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>
在你的代码隐藏中,你需要三个处理程序;一个用于单元格,一个用于每种类型的控件(ComboBox,TextBox):
/// <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();
}