1. 程式人生 > >C# WPF DataGrid控制元件同行編輯的實時更新問題

C# WPF DataGrid控制元件同行編輯的實時更新問題

    這些天一直在研究WPF,試圖用其來進行資料庫客戶端的製作。DataGrid控制元件以其資料顯示和實時編輯的方便易用,自然是不能不用。

    資料庫程式中,往往要實現多級聯動這一功能以實現範圍的選擇等。本人在實現該功能的過程中發現DataGrid控制元件一個讓人十分崩潰的點,就是在編輯完一個單元格的資料之後,需要將焦點移動到下一行或者別的控制元件後,剛剛編輯完的資料才會被更新到繫結的資料物件中。而如果編輯完一個單元格資料後將焦點移動到其同一行的其他單元格,則剛剛編輯完的資料沒有及時更新(這跟INotifyPropertyChanged介面的實現無關,也跟繫結的方式無關)。這就很容易導致程式出錯,比如使用DataGrid

的模板做“省\市\區”的三級聯動下拉列表,當省的選擇發生改變時,市還是發生改變前的那些選項,這就跪了。

    在各種百度差點就去翻牆GOOGLE之際,看到了這篇文章,問題就解決!善哉善哉,願好人一生平安,祝好人長命百歲。

    由於本人剛剛學WPF,該文章談的一些原理性的東西本人還不太明瞭,就只貼出解決過程,有需要的可以去上面提到的那篇部落格中跟博主交流或者等本人日後瞭然了些來更新這篇部落格的原理部分。

    一.新增一個新類,叫做DataGridHelper,會使用到如下的名稱空間:

using System.Windows;
using System.Windows.Controls;
    類的宣告如下:
public static class DataGridHelper
{
    public static void SetRealTimeCommit(DataGrid dataGrid, bool isRealTime)
    {
        dataGrid.SetValue(RealTimeCommitProperty, isRealTime);
    }

    public static bool GetRealTimeCommit(DataGrid dataGrid)
    {
        return (bool)dataGrid.GetValue(RealTimeCommitProperty);
    }

    public static readonly DependencyProperty RealTimeCommitProperty =
    DependencyProperty.RegisterAttached("RealTimeCommit", typeof(bool),
    typeof(DataGridHelper),
    new PropertyMetadata(false, RealTimeCommitCallBack));

    private static void RealTimeCommitCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var dg = d as DataGrid;
        if (dg == null)
            return;
        EventHandler<DataGridCellEditEndingEventArgs> ceHandler = delegate (object xx, DataGridCellEditEndingEventArgs yy)
        {
            var flag = GetRealTimeCommit(dg);
            if (!flag)
                return;
            var cellContent = yy.Column.GetCellContent(yy.Row);
            if (cellContent != null && cellContent.BindingGroup != null)
                cellContent.BindingGroup.CommitEdit();
        };
        dg.CellEditEnding += ceHandler;
        RoutedEventHandler eh = null;
        eh = (xx, yy) =>
        {
            dg.Unloaded -= eh;
            dg.CellEditEnding -= ceHandler;
        };
        dg.Unloaded += eh;
    }
}
    二.在希望控制元件更新資料的時候,使用如下程式碼:
DataGridHelper.SetRealTimeCommit(dataGrid, true);//dataGrid為控制元件名稱
    更新問題便解決了!