Я предполагаю, что это, вероятно, легко, но я застрял.У меня есть поле со списком, данные которого я могу обновить в конструкторе модели представления, но я не могу обновить представление, если я устанавливаю данные после инициализации модели представления.Я предполагаю, что это связано либо с моим DataContext, либо с моей трансляцией событий, но я либо что-то упускаю, либо что-то не понимаю.
Кроме того, я получаю ошибку пути привязки, связанную с моим свойством DataPane., сказав, что его нельзя найти в RedViewModel.Консоль перестает жаловаться, если я помещаю определение свойства для DataPane в RedViewModel, но код работает в обоих сценариях.DataPane - это DataContext для моего MainView, а не для RedView, поэтому я не совсем уверен, почему это так.Это может или не может быть соответствующей справочной информации;В основном меня интересует первая часть этого вопроса.
Вот мой XAML:
<UserControl x:Class="TableBuilder.Views.RedView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:views="clr-namespace:TableBuilder.Views"
xmlns:viewmodels="clr-namespace:TableBuilder.ViewModels"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.DataContext>
<viewmodels:RedViewModel />
</UserControl.DataContext>
<StackPanel Background="Red">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
</Grid.ColumnDefinitions>
<TextBlock Text="Type:" Grid.Column="1" />
<TextBlock Text="Enumeration" Grid.Column="3" />
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
</Grid.ColumnDefinitions>
<TextBlock Text="Value:" Grid.Column="1" />
<ComboBox Grid.Column="3" ItemsSource="{Binding EnumValueItems}" VerticalAlignment="Top">
</ComboBox>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
</Grid.ColumnDefinitions>
<TextBlock Text="Units:" Grid.Column="1" />
<TextBlock Text="Integer" Grid.Column="3" />
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
</Grid.ColumnDefinitions>
<TextBlock Text="Description:" Grid.Column="1" />
<TextBlock Text="text" Grid.Column="3" />
</Grid>
</StackPanel>
Вот модель представления:
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Data;
using TableBuilder.Helpers;
using TableBuilder.Models;
namespace TableBuilder.ViewModels
{
public class RedViewModel : ViewModelBase
{
private object _dataPane;
public object DataPane
{
get { return _dataPane; }
private set
{
_dataPane = value;
OnPropertyChanged(nameof(DataPane));
}
}
private ListCollectionView _enumValueItems;
public ListCollectionView EnumValueItems
{
get { return _enumValueItems; }
set
{
_enumValueItems = value;
OnPropertyChanged(nameof(EnumValueItems));
}
}
public bool Loaded { get; set; }
private ObservableCollection<string> _listData;
public ObservableCollection<string> ListData
{
get { return _listData; }
set
{
_listData = value;
EnumValueItems = new ListCollectionView(ListData);
//EnumValueItems.MoveCurrentTo(ListData[0]);
//OnPropertyChanged("ListData");
}
}
public RedViewModel()
{
//_listData = new ObservableCollection<string>();
//EnumValueItems = new ListCollectionView(_listData);
//EnumValueItems.CurrentChanged += enumValueItems_CurrentChanged;
//GetListData();
}
public void GetListData()
{
ListData = new ObservableCollection<string>();
RedModel model = new RedModel();
ListData = model.GetListData();
//EnumValueItems = new ListCollectionView(model.GetListData());
//EnumValueItems.MoveCurrentTo(ListData[0]);
//EnumValueItems.CurrentChanged += EnumValueItems_CurrentChanged;
}
private void EnumValueItems_CurrentChanged(object sender, EventArgs e)
{
if (Loaded)
{
MessageBox.Show((((ListCollectionView)sender).CurrentItem).ToString());
}
Loaded = true;
}
}
}
Мой класс ViewModelBase находится здесь:
using System.ComponentModel;
using TableBuilder.Models;
using TableBuilder.ViewModels;
namespace TableBuilder.Helpers
{
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Редактировать: Вот тестовый код, который я использую, чтобы попытаться изменить данные списка:
public MainViewModel()
{
OpenCommand = new RelayCommand(ExecuteOpen);
ExitCommand = new RelayCommand(ExecuteExit);
var vm = new RedViewModel();
var test = new ObservableCollection<string>();
test.Add("Test1");
test.Add("Test2");
test.Add("Test3");
test.Add("Test4");
test.Add("Test5");
test.Add("Test6");
test.Add("Test7");
vm.EnumValueItems.Clear();
foreach (string s in test) { vm.EnumValueItems.Add(s); }
DataPane = vm;
}
Я предполагаю, что, скорее всего, здесь каким-то образом нарушена привязка данных.
Редактировать 2:
Чтобы обеспечить дополнительный контекст и ясность для вопроса, вот общееАрхитектура этой программы (в лучшую или в худшую сторону):
Эта программа представляет собой специализированный синтаксический анализатор XML, который используется для создания таблиц конфигурации для встроенного программного обеспечения на основе определения XML.В правой части экрана отображаются соответствующие части данных XML, основанные на узле дерева, выбранном пользователем.Есть различные представления, которые должны отображаться слева, в ожидании, выбрал ли пользователь переменную, которая является enum / float32 / struct / etc.Код, который меня сейчас интересует, - это представление Enum, поэтому есть раскрывающееся меню, в котором должны быть указаны возможные значения enum, основанные на определении XML.
Я пытаюсь заполнитьраскрывающееся меню в RedViewModel (которое станет моим средством просмотра enum при очистке, как только я получу все работающее по назначению) из MainViewModel.Если я заполню список в конструкторе RedViewModel, он будет отображаться правильно.Однако, если я заполню его где-либо еще (в приведенном мною примере я заполнил его в конструкторе MainViewModel после того, как был создан экземпляр RedViewModel), он не обновляется.