2016-01-13 95 views
1

我有一个基本的DataGrid我使用创建的敌人名单的游戏项目我一直在玩弄:WPF绑定到的ObservableCollection - 只有当行完成更新集合

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

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

我怎样才能让DataGrid迫不及待地让我有所有我需要的参数创建对象时执行此更新?

回答

2

我不知道一个直接的方式来做你想做的事情。如果您唯一的选择是在数据网格中进行编辑,则可能需要为与您的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 })); 

,但问题是,填充值不会得到他们周围的红色框。所以,如果你有某种“保存”或“提交”按钮,你需要检查你的视图模型项目的空白值,并提出警告,以便用户解决这个问题。


如果你不绝对需要在数据网络中编辑,你可以使用它只是显示你的数据,并创建一个小的形式与各领域取得自己的标签和文本框(或其他输入控件品牌最有意义的)。当用户提交时,你会把它添加到你的可观察集合中,并且表格会自动更新。这可能会有更多的工作,但会让您对用户界面有更多的控制权,并可能带来更好的用户体验。

相关问题