Esto es un poco hacky, pero lo tengo para trabajar (suponiendo que entiendo lo que quieres).
primera vez que crea una clase de vista del modelo:
class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
this.data.Add(1, "One");
this.data.Add(2, "Two");
this.data.Add(3, "Three");
}
Dictionary<int, string> data = new Dictionary<int, string>();
public IDictionary<int, string> Data
{
get { return this.data; }
}
private KeyValuePair<int, string>? selectedKey = null;
public KeyValuePair<int, string>? SelectedKey
{
get { return this.selectedKey; }
set
{
this.selectedKey = value;
this.OnPropertyChanged("SelectedKey");
this.OnPropertyChanged("SelectedValue");
}
}
public string SelectedValue
{
get
{
if(null == this.SelectedKey)
{
return string.Empty;
}
return this.data[this.SelectedKey.Value.Key];
}
set
{
this.data[this.SelectedKey.Value.Key] = value;
this.OnPropertyChanged("SelectedValue");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
var eh = this.PropertyChanged;
if(null != eh)
{
eh(this, new PropertyChangedEventArgs(propName));
}
}
}
Y luego, en el XAML:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListBox x:Name="ItemsListBox" Grid.Row="0"
ItemsSource="{Binding Path=Data}"
DisplayMemberPath="Key"
SelectedItem="{Binding Path=SelectedKey}">
</ListBox>
<TextBox Grid.Row="1"
Text="{Binding Path=SelectedValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</Window>
El valor de la propiedad Data
se une a la ItemsSource
del ListBox
. Como indica en la pregunta, esto da como resultado el uso de instancias de KeyValuePair<int, string>
como datos detrás del ListBox
. Establecí DisplayMemberPath
en Key
para que el valor de la clave se use como el valor mostrado para cada elemento en el ListBox
.
Como has encontrado, no puedes usar el Value
del KeyValuePair
como datos para el TextBox
, ya que es de solo lectura. En su lugar, el TextBox
está vinculado a una propiedad en el modelo de vista que puede obtener y establecer el valor de la clave seleccionada actualmente (que se actualiza vinculando la propiedad SelectedItem
del ListBox
a otra propiedad en el modelo de vista). Tuve que hacer esta propiedad nullable (ya que KeyValuePair
es una estructura), por lo que el código podría detectar cuando no hay selección.
En mi aplicación de prueba, este parece ser el resultado de las modificaciones a la TextBox
que se propagan a la Dictionary
en el modelo de vista.
¿Es eso más o menos lo que está buscando? Parece que debería ser un poco más limpio, pero no estoy seguro de si hay alguna manera de hacerlo.
¿No sería mejor usar algo como un ObservableDictionary con WPF? – Rauhotz
¿Cómo vas a hacer las dos cosas? ¿Se muestran los valores en un cuadro de texto? – Ray
@Ray Tengo un editor personalizado para mis valores. Si tuviera un ejemplo con un TextBox, estoy seguro de que podría hacer que se ajuste a mis necesidades. –