You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Avalonia DataGrid跨列更新属性时单元格值不同步问题

问题场景

使用WPF DataGrid控件实现两列绑定到同一EntryLog模型的Date属性,列定义如下XAML:

<DataGrid
    Margin="10"
    BorderBrush="Black"
    BorderThickness="1"
    Grid.Row="1"
    Grid.ColumnSpan="3"
    Items="{Binding Logs}"
    AutoGenerateColumns="False"
    >
    <DataGrid.Columns>
        <DataGridTextColumn
            Header="Temp Date"
            Binding="{Binding Date,Mode=TwoWay}"
            >
        </DataGridTextColumn>
        <DataGridTemplateColumn
            Header="Calendar Column"
            CellTemplate="{Binding TestTemplate}"
            CellEditingTemplate="{Binding EditingTemplate}"
            >
            
        </DataGridTemplateColumn>
    </DataGrid.Columns>
    
</DataGrid>

ViewModel中通过代码动态创建单元格模板,普通显示状态的CellTemplate定义:

// Cell Data Template
 TestTemplate = new FuncDataTemplate<EntryLog>((value, namescope) =>

   new TextBlock
   {
       [!TextBlock.TextProperty] = new Binding("Date",BindingMode.TwoWay),
   });

编辑状态的CellEditingTemplate定义:

// Cell Editing Data Template
EditingTemplate = new FuncDataTemplate<EntryLog>((value, namescope) =>
{
    var grid = new Grid();
    var tb = new TextBlock
    {
        [!TextBlock.TextProperty] = new Binding("Date", BindingMode.TwoWay),
    };
    grid.Children.Add(tb);

    var calendar = new Calendar();
    calendar.DisplayDate = value.Date;
    calendar.SelectedDate = value.Date;

    Popup popup = new Popup();
    popup.Child = calendar;
    popup.IsOpen = true;


    calendar.SelectedDatesChanged += (s, e) => 
    {
        value.Date = calendar.SelectedDate.Value.Date;
        //tb.Text = value.Date.ToString();

    };
    grid.Children.Add(popup);
    
    return grid;
});

编辑态UI效果:
Datagrid编辑态日历选择效果

核心故障:任意一列修改绑定的Date属性值时,另一列的单元格值不会同步更新。
已知配置:DataGrid的ItemsSource绑定EntryLog类型的ObservableCollection集合,EntryLog已实现INotifyPropertyChanged接口,模型代码如下:

public class EntryLog : INotifyPropertyChanged
{
    private DateTime _date;
    public DateTime Date
    {
        get => _date;
        set
        {
            if (_date != value)
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Date)));

            _date = value;
        }
    }
    public string Description { get; set; }
    public double Hours { get; set; }

    public event PropertyChangedEventHandler? PropertyChanged;
}
根因定位

故障由3处实现错误共同导致:

  • EntryLog的属性通知逻辑顺序错误:当前Date属性的set块中,先触发PropertyChanged事件,再给后备字段_date赋值。事件触发时UI读取到的还是旧值,绑定系统拿到旧值不会刷新显示。
  • 编辑模板内Calendar控件未正确绑定到Date属性:编辑态的Calendar控件直接通过代码赋值DisplayDate和SelectedDate,没有建立和Date属性的双向绑定,选择日期时直接手动给value.Date赋值,绕过了WPF的绑定更新流转逻辑,加上DataGrid行编辑状态下默认会缓存编辑值,不会主动刷新其他列的显示。
  • XAML中DataGrid的数据源属性拼写错误:原XAML写的是Items="{Binding Logs}",DataGrid接收列表数据源的属性是ItemsSource,拼写错误会导致绑定无法正常工作,集合和属性的变更通知无法被DataGrid正确接收。
修复方案

按以下步骤修改即可解决两列值不同步的问题:

  1. 修正EntryLog的Date属性通知顺序,先更新字段值再触发变更事件
public DateTime Date
{
    get => _date;
    set
    {
        if (_date != value)
        {
            _date = value; // 先更新字段存储值
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Date))); // 再发送变更通知
        }
    }
}
  1. 修正XAML中DataGrid的数据源绑定属性名,把Items改为ItemsSource
  2. 修改编辑模板中Calendar的实现,建立和Date属性的双向绑定,移除手动赋值的事件逻辑:
EditingTemplate = new FuncDataTemplate<EntryLog>((value, namescope) =>
{
    var grid = new Grid();
    var tb = new TextBlock
    {
        [!TextBlock.TextProperty] = new Binding("Date", BindingMode.TwoWay),
    };
    grid.Children.Add(tb);

    var calendar = new Calendar();
    // 为Calendar的SelectedDate建立双向绑定,替换原有手动赋值逻辑
    calendar.SetBinding(Calendar.SelectedDateProperty, new Binding("Date")
    {
        Mode = BindingMode.TwoWay,
        UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
    });

    Popup popup = new Popup();
    popup.Child = calendar;
    popup.IsOpen = true;
    // 移除手动给value.Date赋值的事件处理,绑定机制会自动完成值流转同步
    grid.Children.Add(popup);
    
    return grid;
});

内容的提问来源于stack exchange,提问作者Jeremy Loh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 16:36:29