WPF绑定到ObservableCollection - 仅在行完成时更新集合

时间:2016-01-13 21:01:18

标签: c# wpf datagrid

我有一个基本的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绑定到从ObservableCollection文件读入的json

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类创建了一个空构造函数。只要在Name上的EnemyGrid字段中键入第一个字符,集合就会尝试更新,并且我会获得Enemy类上大多数属性的默认值。

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

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

1 个答案:

答案 0 :(得分:2)

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

所以,如果你的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 }));

但问题是,未填充的值不会在它们周围出现红色框。因此,如果您有某种“保存”或“提交”按钮,则需要检查您的视图模型项是否有空白值,并发出警告以便用户进行修复。

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