与类的成员变量的WPF数据绑定

本文关键字:WPF 数据绑定 变量 成员 | 更新日期: 2023-09-27 18:20:26

我有一个这样的类。

public class ViewModel
{
    public PengChat3ClientSock Sock { get; internal set; }
    public ObservableCollection<Room> Rooms { get; internal set; }
    public ViewModel(PengChat3ClientSock sock)
    {
        Sock = sock;
        Rooms = new ObservableCollection<Room>();
    }
}

MainWindow.xaml.cs

public ObservableCollection<ViewModel> viewModel { get; set; }

(当然它已经初始化了。)

这是一个构造函数。

comboBox.ItemsSource = viewModel;

但在这里,我不想使用viewModel,只想使用viewModel.Sock

我该怎么做?

与类的成员变量的WPF数据绑定

没有viewModel.Sock,因为viewModel是viewModel类型的对象的集合,包含该属性。

根据您的目标,有不同的解决方案:

  • 您仍然可以将comboBox绑定到viewModel,但在comboBox的项目模板中,您可以访问Sock属性

  • 您可以创建仅包含Sock对象的新集合。。。但是,您可能必须确保它与ViewModel对象的集合同步

通常你会用一种稍微不同的方式来处理这个问题:

  1. 创建视图(具有所需所有ui元素的UserControl)
  2. 在新创建的视图上将"ViewModel"设置为DataContext(userControl.DataContext=ViewModel)
  3. 在定义组合框的视图中,现在可以通过Bindings直接引用视图模型上的"Sock"属性

代码:

<ComboBox ItemsSource="{Binding Sock}"/>

如果你只想从代码后面设置ItemsSource,这有点难看,你可以简单地将Sock中的项目添加到comboBox中。items-或者,你可能需要从代码后面创建一个新的"Binding"对象,但这更难看:

var binding = new Binding("Sock")
{
    Source = viewModel
};
comboBox.ItemsSource = binding;

请注意,我还没有测试过"在代码背后绑定方法",这样做确实是一种反模式,尤其是在使用MVVM的情况下。

此外,您的"Sock"属性是一个类,而不是一个集合,所以您将无法真正做到这一点;您可能是指ViewModel的"Rooms"属性吗?

您只能将ItemsSource绑定到实现IEnumerable的类型。我以前遇到过这种情况,并制作了一个转换器将任何对象转换为列表。这是一个简单且可重复使用的解决方案,它将ViewModel逻辑与视图逻辑分离:

转换器:

public class ItemToCollectionConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return new List<object> { value };
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

XAML

<UserControl.Resources>
    <local:ItemToCollectionConverter x:Key="ItemToCollectionConverter"/>
</UserControl.Resources>
...
<ComboBox ItemsSource="{Binding Sock, Converter={StaticResource ItemToCollectionConverter}}"/>