与类的成员变量的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
。
我该怎么做?
没有viewModel.Sock,因为viewModel是viewModel类型的对象的集合,包含该属性。
根据您的目标,有不同的解决方案:
-
您仍然可以将comboBox绑定到viewModel,但在comboBox的项目模板中,您可以访问Sock属性
-
您可以创建仅包含Sock对象的新集合。。。但是,您可能必须确保它与ViewModel对象的集合同步
通常你会用一种稍微不同的方式来处理这个问题:
- 创建视图(具有所需所有ui元素的UserControl)
- 在新创建的视图上将"ViewModel"设置为DataContext(userControl.DataContext=ViewModel)
- 在定义组合框的视图中,现在可以通过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}}"/>