【问题标题】:Update DataGrid's ItemsSource on SelectionChanged event of a ComboBox在 ComboBox 的 SelectionChanged 事件上更新 DataGrid 的 ItemsSource
【发布时间】:2013-10-22 03:38:06
【问题描述】:

我在DataGrid 中的ComboBox 上使用以下代码订阅了SelectionChangedEvent

public static DataGridTemplateColumn CreateComboboxColumn(string colName, Binding textBinding, SelectionChangedEventHandler selChangedHandler = null)
{
    var cboColumn = new DataGridTemplateColumn {Header = colName};
...
    if (selChangedHandler != null)
        cboFactory.AddHandler(Selector.SelectionChangedEvent, selChangedHandler);
...
    return cboColumn;
}

我实际注册的处理程序包含:

private void ComboBoxSelectionChangedHandler(object sender, SelectionChangedEventArgs e)
{
    Console.WriteLine(@"selectHandler");
    var cboBox = sender as ComboBox;
    if (cboBox == null)
        return;

    if (cboBox.IsDropDownOpen) // a selection in combobox was made
    {
        CommitEdit();
    }
    else // trigger the combobox to show its list
        cboBox.IsDropDownOpen = true;
}

...并且位于我的自定义 DataGrid 类中。

如果我在 ComboBox 中选择一个项目,e.AddedItemscboBox.SelectedItem 包含所选值,但 CommitEdit() 上没有任何更改。

我想要的是在用户选择下拉列表中的项目时强制提交直接更新DataGrid 的ItemsSource。通常,如果控件失去焦点,则会引发此问题...

this thread 中找到的解决方案中的链接不再可用,我不知道如何使用此代码。

【问题讨论】:

    标签: c# wpf .net-4.0 datagrid


    【解决方案1】:

    我为我的问题创建了一个棘手但有效的解决方案。这是上面修改后的处理程序:

    private void ComboBoxSelectionChangedHandler(object sender, SelectionChangedEventArgs e)
    {
        Console.WriteLine(@"selectHandler");
        var cboBox = sender as ComboBox;
        if (cboBox == null)
            return;
    
        if (cboBox.IsDropDownOpen) // a selection in combobox was made
        {
            cboBox.Text = cboBox.SelectedValue as string;
            cboBox.MoveFocus(new TraversalRequest(FocusNavigationDirection.Right));
        }
        else // user wants to open the combobox
            cboBox.IsDropDownOpen = true;
    }
    

    因为我的 ComboBoxColumn 是自定义的 DataGridTemplateColumn,所以当用户第一次选择单元格时,我会强制它显示其列表。

    要更改绑定项目的值,我用最近选择的项目手动覆盖显示的文本并强制 UI 选择另一个项目(在本例中为右侧的控件)以隐式调用 CellEditEnding 事件,其中 (在我的情况下)提交整行:

    private bool _isManualEditCommit = false;
    private void _CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
    {
        // commit a manual edit
        // this if-clause prevents double execution of the EditEnding event
        if (!_isManualEditCommit)
        {   
            Console.WriteLine(@"_CellEditEnding() manualeditcommit");
            _isManualEditCommit = true;
            CommitEdit(DataGridEditingUnit.Row, true);
            _isManualEditCommit = false;
            checkRow(e.Row);
        }
    }
    

    也许我可以用这个“肮脏”的解决方案帮助别人;-)

    【讨论】:

    • 对于在使用DataGridComboBoxColumn 时遇到此答案的人,请注意,单独使用_CellEditEnding 足以让它更新基础项目;您不需要使用第一段代码。
    猜你喜欢
    • 1970-01-01
    • 2014-07-27
    • 1970-01-01
    • 2013-06-30
    • 2017-07-15
    • 2015-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多