Caliburn.Micro - 将 ValueTuple 的 ObservableCollection 绑定到 ComboBox
Caliburn.Micro - Binding ObservableCollection of ValueTuple to ComboBox
我正在尝试使用 Caliburn.Micro 框架 MVVM 将 ValueTuples 的 ObservableCollection 绑定到 WPF 中的 ComboBox。当我在 ViewModel 中这样做时:
private ObservableCollection<Tuple<string, string>> databasesFromDisk;
public ObservableCollection<Tuple<string, string>> DatabasesFromDisk
{
get => databasesFromDisk;
set
{
databasesFromDisk = value;
NotifyOfPropertyChange(() => DatabasesFromDisk);
}
}
并在 XAML 视图中:
<ComboBox x:Name="DatabasesFromDisk" DisplayMemberPath="Item1"/>
有效,ComboBox 填充第一个字符串。但是当我尝试使用 C# 7 并更改为:
private ObservableCollection<(string name, string path)> databasesFromDisk;
public ObservableCollection<(string name, string path)> DatabasesFromDisk
{
get => databasesFromDisk;
set
{
databasesFromDisk = value;
NotifyOfPropertyChange(() => DatabasesFromDisk);
}
}
当我不更改时它不起作用 XAML - 它显示空列表。当我更改为 DisplayMemberPath="name"
- 相同的空列表时它不起作用。当我删除 DisplayMemberPath
时它不能正常工作 - 它显示整个列表但两个字符串连接在一起。
我怎样才能用 ValueTuples 做到这一点?
在 C# 7 之前,元组的所有项都是可绑定的属性。在 C# 7 中,ValueTuple 是不可绑定的字段。
https://msdn.microsoft.com/en-us/library/dd386940(v=vs.110).aspx
https://github.com/dotnet/corefx/blob/master/src/System.ValueTuple/src/System/ValueTuple/ValueTuple.cs#L291
一种可能的解决方案是使用 IValueConverter
public class ValueTupleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var tuple = value as (string name, string path)?;
if (tuple == null)
return null;
return tuple.Value.Name;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
<ComboBox x:Name="DatabasesFromDisk">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource ValueTupleConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
我正在尝试使用 Caliburn.Micro 框架 MVVM 将 ValueTuples 的 ObservableCollection 绑定到 WPF 中的 ComboBox。当我在 ViewModel 中这样做时:
private ObservableCollection<Tuple<string, string>> databasesFromDisk;
public ObservableCollection<Tuple<string, string>> DatabasesFromDisk
{
get => databasesFromDisk;
set
{
databasesFromDisk = value;
NotifyOfPropertyChange(() => DatabasesFromDisk);
}
}
并在 XAML 视图中:
<ComboBox x:Name="DatabasesFromDisk" DisplayMemberPath="Item1"/>
有效,ComboBox 填充第一个字符串。但是当我尝试使用 C# 7 并更改为:
private ObservableCollection<(string name, string path)> databasesFromDisk;
public ObservableCollection<(string name, string path)> DatabasesFromDisk
{
get => databasesFromDisk;
set
{
databasesFromDisk = value;
NotifyOfPropertyChange(() => DatabasesFromDisk);
}
}
当我不更改时它不起作用 XAML - 它显示空列表。当我更改为 DisplayMemberPath="name"
- 相同的空列表时它不起作用。当我删除 DisplayMemberPath
时它不能正常工作 - 它显示整个列表但两个字符串连接在一起。
我怎样才能用 ValueTuples 做到这一点?
在 C# 7 之前,元组的所有项都是可绑定的属性。在 C# 7 中,ValueTuple 是不可绑定的字段。
https://msdn.microsoft.com/en-us/library/dd386940(v=vs.110).aspx https://github.com/dotnet/corefx/blob/master/src/System.ValueTuple/src/System/ValueTuple/ValueTuple.cs#L291
一种可能的解决方案是使用 IValueConverter
public class ValueTupleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var tuple = value as (string name, string path)?;
if (tuple == null)
return null;
return tuple.Value.Name;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
<ComboBox x:Name="DatabasesFromDisk">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource ValueTupleConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>