2016-01-13 2 views
1

У меня есть основной DataGrid, что я использую, чтобы создать список врагов для игрового проекта я играл с:WPF Binding к 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 привязан к 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 wait, чтобы выполнить это обновление, чтобы у меня были все мои требуемые параметры, когда объект был создан?

ответ

2

Я не знаю, как правильно сделать то, что вы пытаетесь сделать. Если ваш единственный вариант заключается в редактировании в сетке данных, вам может понадобиться создать EnemyViewModel для ваших данных, которые имеют те же свойства, что и ваш Enemy, за исключением того, что каждое свойство имеет значение NULL.

Так что, если ваш 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 (или любой входной виджет марок самый лучший смысл). Когда пользователь отправит это сообщение, вы добавите его в свою наблюдаемую коллекцию, и таблица автоматически обновится. Это будет немного больше работы, но даст вам намного больше контроля над пользовательским интерфейсом и может привести к улучшению пользовательского интерфейса.

Смежные вопросы