2

我正在尝试使用 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 做到这一点?

4

1 回答 1

0

在 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/系统/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>

于 2017-07-25T05:58:31.760 回答