WPF 绑定到可观察集合 - 仅在行完成时更新集合

本文关键字:集合 完成时 更新 观察 WPF 绑定 | 更新日期: 2023-09-27 18:30:16

我有一个基本DataGrid,我用它来为我一直在玩的游戏项目创建敌人列表:

<DataGrid x:Name="EnemyGrid" Margin="0,10,0,0" VerticalAlignment="Top" RenderTransformOrigin="8.273,3.781" Height="162" ItemsSource="{Binding}" CanUserReorderColumns="False" ColumnWidth="*" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Name, UpdateSourceTrigger=Explicit}" ClipboardContentBinding="{x:Null}" Header="Name"/>
        <DataGridTextColumn Binding="{Binding Level, UpdateSourceTrigger=Explicit}" ClipboardContentBinding="{x:Null}" Header="Level"/>
        <DataGridTextColumn Binding="{Binding Role, UpdateSourceTrigger=Explicit}" ClipboardContentBinding="{x:Null}" Header="Role"/>
    </DataGrid.Columns>
</DataGrid>

DataGrid绑定到从json文件中读入的ObservableCollection

public partial class MainWindow : Window
{
    public ObservableCollection<Enemy> EnemyList;
    public MainWindow()
    {
        InitializeComponent();
        var data = JsonHelpers.ReadFile<Enemy>("Enemy.json");
        EnemyList = data["Enemy"];
        EnemyGrid.DataContext = EnemyList;
     }
}

如果重要,ReadFile 方法使用 JSON.Net

public static Dictionary<string, ObservableCollection<T>> ReadFile<T>(this string fileName)
{
    string text = File.ReadAllText(dataPath + fileName);                        
    Dictionary<string, ObservableCollection<T>> data = JsonConvert.DeserializeObject<Dictionary<string, ObservableCollection<T>>>(text);
    return data;
}

旁注:返回类型Dictionary<string, ObservableCollection<T>>,因为我需要在json文件中维护表声明。如果我可以在没有这个的情况下保持"TableName" : [{Table}]格式,那么我将不胜感激。

简而言之,我遇到的问题与DataGrid何时发布更新有关。根据一些相关问题,我为 Enemy 类创建了一个空构造函数。一旦我在EnemyGridName字段中键入第一个字符,集合就会尝试更新,并且我获得了Enemy类上大多数属性的默认值。

另请注意,尽管我已经在列上设置了UpdateSourceTrigger=Explicit,但一旦我开始键入,集合就会继续更新。理想情况下,我希望在完成row中添加值后创建对象,但是一旦编辑了cell,就会进行更新。

如何使DataGrid等待执行此更新,以便在创建对象时拥有所有必需的参数?

WPF 绑定到可观察集合 - 仅在行完成时更新集合

我不知道

有什么直接的方法可以做你想做的事情。如果唯一的选择是在数据网格中进行编辑,则可能需要为数据创建一个与Enemy具有相同属性的EnemyViewModel,但每个属性都可为空。

因此,如果您的Enemy如下所示:

public class Enemy
{
    public string Name { get; set; }
    public int Level { get; set; }
    public Role Role { get; set; }
}

。您的EnemyViewModel如下所示:

public class EnemyViewModel
{
    public string Name { get; set; }
    public int? Level { get; set; }
    public Role? Role { get; set; }
}

这样,表行中所有内容的默认值都将null ,这将对用户显示为空白/未填充。

一个简单的 LINQ 查询将允许您将从 JSON 读取的敌人转换为ObservableCollection<EnemyViewModel>

EnemyGrid.DataContext =
    new ObservableCollection<EnemyViewModel>(
        enemies.Select(x => new EnemyViewModel { Name = x.Name, Level = x.Level, Role = x.Role }));

但是,问题在于未填充的值不会在其周围显示一个红色框。因此,如果您有某种"保存"或"提交"按钮,则需要检查视图模型项中的空白值,并向用户发出警告以解决此问题。


如果您不是绝对需要在数据网格中进行编辑,则可以仅将其用于显示数据,并创建一个小表单,每个字段都有自己的标签和文本框(或任何最有意义的输入小部件)。当用户提交此内容时,您将将其添加到可观察集合中,并且表将自动更新。这将需要更多的工作,但可以让您更好地控制用户界面,并可能带来更好的用户体验。

相关文章: