Đây là một chút hacky, nhưng tôi đã nhận nó để làm việc (giả sử rằng tôi hiểu những gì bạn muốn).
đầu tiên tôi tạo ra một lớp xem mô hình:
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));
}
}
}
Và sau đó trong 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>
Giá trị của tài sản Data
được ràng buộc với ItemsSource
của ListBox
. Khi bạn nêu trong câu hỏi, điều này dẫn đến việc sử dụng các trường hợp KeyValuePair<int, string>
làm dữ liệu đằng sau số ListBox
. Tôi đặt DisplayMemberPath
thành Key
để giá trị của khóa sẽ được sử dụng làm giá trị được hiển thị cho mỗi mục trong ListBox
.
Như bạn đã tìm thấy, bạn không thể chỉ sử dụng Value
của số KeyValuePair
làm dữ liệu cho số TextBox
, vì đó là chỉ đọc. Thay vào đó, TextBox
được gắn với thuộc tính trên mô hình chế độ xem có thể nhận và đặt giá trị cho khóa hiện được chọn (được cập nhật bằng cách gắn thuộc tính SelectedItem
của ListBox
cho thuộc tính khác trên mô hình chế độ xem). Tôi phải làm cho thuộc tính này có thể vô hiệu hóa (vì KeyValuePair
là một cấu trúc), để mã có thể phát hiện khi không có lựa chọn nào.
Trong ứng dụng thử nghiệm của tôi, điều này dường như dẫn đến việc chỉnh sửa để TextBox
truyền đến Dictionary
trong mô hình chế độ xem.
Đó có phải là nhiều hay ít những gì bạn đang làm? Nó có vẻ như nó phải là một chút sạch hơn, nhưng tôi không chắc chắn nếu có bất kỳ cách nào để làm như vậy.
Bạn có nên sử dụng cái gì đó như ObservableDictionary với WPF không? – Rauhotz
Làm thế nào bạn sẽ làm cho nó hai chiều? Giá trị của chúng có được hiển thị trong một TextBox không? – Ray
@Ray Tôi có trình chỉnh sửa tùy chỉnh cho Giá trị của mình. Nếu tôi có một ví dụ với một TextBox, tôi chắc chắn rằng tôi có thể làm cho nó đáp ứng nhu cầu của tôi. –