Я пытаюсь создать UserControl, который позволит мне редактировать словарь типа Dictionary<string,string>
в сетке (только редактируя записи до сих пор, не добавляя или не удаляя).Почему в моем ViewModel не изменяется свойство, когда изменяется DataGrid?
Всякий раз, когда я привязать DataGrid к словарю он показывает сетку только для чтения, так что я decieded создать преобразователь значений, что бы преобразовать его в ObservableCollection<DictionaryEntry>
где DictionaryEntry
просто класс с двумя свойствами Key
и Value
.
Это работает для отображения словаря в сетке, но теперь, когда я вношу изменения в сетку, мой словарь не обновляется. Я не знаю, почему.
Я думаю, что это либо проблема с тем, как у меня установлены привязки, либо мой конвертер значений. Если бы кто-нибудь мог пролить свет, это было бы фантастически.
Ниже представлена самая маленькая демонстрация, которую я мог бы сделать, чтобы показать, что я делаю. Опять проблема заключается в том, что когда я изменяю значения в сетке, MyDictionary
на моем MainViewModel
не обновляется ... Зачем?
MainViewModel.cs
public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel()
{
_myDictionary = new Dictionary<string, string>()
{
{"Key1", "Value1"},
{"Key2", "Value2"},
{"Key3", "Value3"}
};
}
private Dictionary<string, string> _myDictionary;
public Dictionary<string, string> MyDictionary
{
get
{
return _myDictionary;
}
set
{
if (_myDictionary == value)
return;
_myDictionary = value;
OnPropertyChanged("MyDictionary");
}
}
...
}
MainWindow.xaml
<Window ...>
<Window.Resources>
<local:MainViewModel x:Key="MainViewModel"></local:MainViewModel>
</Window.Resources>
<StackPanel Name="MainStackPanel" DataContext="{Binding Source={StaticResource MainViewModel}}">
<local:DictionaryGrid />
<Button Content="Print Dictionary" Click="PrintDictionary"></Button>
</StackPanel>
</Window>
DictionaryGrid.xaml
<UserControl ...>
<UserControl.Resources>
<testingGrid:DictionaryToOcConverter x:Key="Converter" />
</UserControl.Resources>
<Grid>
<DataGrid ItemsSource="{Binding MyDictionary,
Converter={StaticResource Converter}}"
/>
</Grid>
</UserControl>
DictionaryToOcConverter.cs
public class DictionaryToOcConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var collection = new ObservableCollection<DictionaryEntry>();
var dictionary = value as Dictionary<string, string>;
if (dictionary != null)
{
foreach (var kvp in dictionary)
collection.Add(new DictionaryEntry { Key = kvp.Key, Value = kvp.Value });
}
return collection;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var dictionary = new Dictionary<string, string>();
var entries = value as ObservableCollection<DictionaryEntry>;
if (entries != null)
{
foreach (var entry in entries)
dictionary.Add(entry.Key, entry.Value);
}
return dictionary;
}
public class DictionaryEntry
{
public string Key { get; set; }
public string Value { get; set; }
}
}
Благодарим за отзыв. Я сделал эти изменения. Внутренний словарь меняет палку, но они не возвращаются к моей основной модели представления, я пропущу что-то, что мне нужно сделать, чтобы заставить его вернуться через IValueConverter? Метод ConvertBack никогда не вызывается и не уверен в правильном способе его вызова, должен ли он вызываться, когда меняется наблюдаемая коллекция, или мне нужно подключить что-то еще? –
Я не хотел включать его в свой ответ, но конвертер значений в значительной степени является красной селедкой. Я бы это уложил. Если изменения работают (что им нужно!), И вы хотите получать уведомления в еще одном слое абстракции, тогда виртуальная машина должна подписаться на каждое свойство DictionaryEntry и реализовать один обработчик событий для их обработки. Или просто используйте «внутренний словарь» в качестве источника элементов виртуальной машины. –