簡體   English   中英

在CellEditEnding事件上修改DataGrid單元格值

[英]Modifying DataGrid cell values on CellEditEnding event

我一直在嘗試在WPF DataGrid控件的CellEditEnding事件處理程序內的同一行中更改其他單元格值。

如果我在現有行中編輯單元格值,它將按預期工作。 但是,在添加新行時,如果在不進入編輯模式的情況下用鼠標單擊了另一個單元格值,則更改不會反映到UI。

通過按Tab鍵將焦點移到下一個單元格也可以按預期方式工作,但是單擊也不能正常工作嗎?

public MainWindow()
{
    InitializeComponent();

    DataTable dataTable = new DataTable();
    dataTable.Columns.Add(new DataColumn());
    dataTable.Columns.Add(new DataColumn());
    DataRow existingRow = dataTable.NewRow();
    dataTable.Rows.Add(existingRow);

    this.MyDataGrid.ItemsSource = dataTable.DefaultView;
    this.MyDataGrid.CellEditEnding += MyDataGrid_CellEditEnding;
}

void MyDataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
    (e.Row.Item as DataRowView).Row[1] = "a string that should be displayed immediatly";
}

到目前為止,我已經嘗試更改綁定UpdateSourceTrigger,NotifyOnSourceUpdated和NotifyOnTargetUpdated,但是似乎沒有任何效果。 我還嘗試通過閱讀相關主題來進行修正: http : //codefluff.blogspot.fi/2010/05/commiting-bound-cell-changes.html

但是這些似乎也沒有幫助。

我發現可以正常工作的一種方式是以下代碼段:

var frameworkElement = this.MyDataGrid.Columns[1].GetCellContent(e.Row);
frameworkElement.SetValue(TextBlock.TextProperty, "a string that should be displayed immediatly");

但是我不想依賴於dependencyproperties,因為我可能不知道底層的顯示類型。

所以問題是,在不使用提供的第二代碼段的情況下,如何在新行中實現UI更新,因為它可以與現有行一起工作? 我覺得我想念一些東西。

編輯:使用ClipboardPaste也可以用於設置新值,但是由於某些原因,原始的編輯值將丟失。

Edit2:xaml當前是普通的DataGrid,我嘗試手動處理列及其綁定,但是由於我沒有使其工作,因此我刪除了它們以使示例代碼保持簡單

<DataGrid x:Name="MyDataGrid" />

Edit3:添加了此圖像以更好地描述問題。 因此,在單擊下一個單元格后,我希望顯示文本。問題的示例圖像

Edit4:使用snoop查看單元格似乎將元素設置為可見,同時調用.UpdateTarget();。 因為綁定似乎有幫助,但是它不能自動運行。 仍然想知道是什么原因。

Edit5:我希望它可以與DataTable一起使用,因為我需要其他功能

測試了大量不同類型的解決方案后,我最終在開始編輯單元格時添加了該行。 由於我要尋找的功能正在現有行中使用,因此確實解決了該問題。

public class MyDataGrid : DataGrid
{
    protected override void OnBeginningEdit(DataGridBeginningEditEventArgs e)
    {
        base.OnBeginningEdit(e);
        this.CommitEdit();
    }

    protected override void OnCellEditEnding(DataGridCellEditEndingEventArgs e)
    {
        base.OnCellEditEnding(e);
        (e.Row.Item as DataRowView).Row[1] = "a string that should be displayed immediatly";
    }
}

我建議您使用MVVM方式,然后通過WPF本身的內置通知機制滿足您的要求,其中在數據上下文中某些屬性更新時,您可以觸發另一個屬性的更新。 示例:1. Xaml代碼:

<Window x:Class="DataGridSoHelpAttempt.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:dataGridSoHelpAttempt="clr-namespace:DataGridSoHelpAttempt"
    Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
    <dataGridSoHelpAttempt:MainViewModel/>
</Window.DataContext>
<Grid>
    <DataGrid x:Name="MyDataGrid" ItemsSource="{Binding DataSource}"/>
</Grid></Window>

2.查看模型代碼:

public class MainViewModel:BaseObservableObject
{
    public MainViewModel()
    {
        DataSource = new ObservableCollection<BaseData>(new List<BaseData>
        {
            new BaseData {Name = "John"},
            new BaseData {Name = "Ron"},
            new BaseData {Name = "Bob"},
        });
    }
    public ObservableCollection<BaseData> DataSource { get; set; }
}

3.型號代碼:

public class BaseData:BaseObservableObject
{
    private string _name;
    private string _description;

    public virtual string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            OnPropertyChanged();
            Description = "a string that should be displayed immediatly";
        }
    }

    public virtual object Description
    {
        get { return _description; }
        set
        {
            _description = (string) value;
            OnPropertyChanged();
        }
    }
}

4. BaseObservableObject一個基本的INotifyPropertyChanged實現:

public class BaseObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    protected virtual void OnPropertyChanged<T>(Expression<Func<T>> raiser)
    {
        var propName = ((MemberExpression)raiser.Body).Member.Name;
        OnPropertyChanged(propName);
    }

    protected bool Set<T>(ref T field, T value, [CallerMemberName] string name = null)
    {
        if (!EqualityComparer<T>.Default.Equals(field, value))
        {
            field = value;
            OnPropertyChanged(name);
            return true;
        }
        return false;
    }
}

5.請記住,模型的屬性對象可能很復雜(例如描述另一個視圖模型的圖像或類),但是在這種情況下,您必須對數據網格列或單元格進行模板化(示例鏈接: WPF DataGrid Control )。

如果您遇到代碼方面的問題,我將非常樂意提供幫助。 問候

更新 1.后面的代碼-您應該更新DataTable,但是請考慮到必須對Table中已經存在的行執行更新:

public partial class MainWindow : Window
{
    private readonly DataTable _dataTable;

    public MainWindow()
    {
        InitializeComponent();

        this.MyDataGrid.CellEditEnding += MyDataGrid_CellEditEnding;
        _dataTable = new DataTable();
        _dataTable.Columns.Add(new DataColumn());
        _dataTable.Columns.Add(new DataColumn());
        DataRow existingRow = _dataTable.NewRow();
        _dataTable.Rows.Add(existingRow);

        this.MyDataGrid.ItemsSource = _dataTable.DefaultView;

    }


    void MyDataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
    {
        var dataRowView = (e.Row.Item as DataRowView);
        var columnIndex = e.Column.DisplayIndex;
        var rowIndex = e.Row.GetIndex();
        var dv = _dataTable.DefaultView;
        var nextColumnIndex = columnIndex + 1;
        if (dv.Table.Columns.Count <= nextColumnIndex || dv.Table.Rows.Count <= rowIndex) return;
        dv.Table.Rows[rowIndex][nextColumnIndex] = "a string that should be displayed immediatly";
    }
}

2. Xaml:

<Window x:Class="GridViewWitaFDataTableSoHelpAttempt.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <DataGrid x:Name="MyDataGrid" />
</Grid></Window>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM