我有以下实体:
public class User
{
public User()
{
Roles = new ObservableCollection<Role>();
}
public int UserId { get; set; }
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
public virtual ICollection<Role> Roles { get; set; }
}
public class Role
{
public int RoleId { get; set; }
public string Name { get; set; }
public virtual User User { get; set; }
}
使用此ViewModel:
public class UserManagerViewModel : ObservableObject
{
public ObservableCollection<Role> AllRoles { get; set; }
public UserViewModel()
{
AllRoles = new ObservableCollection<Role>(RoleRepository.GetAll());
}
private User _selectedUser;
public User SelectedUser
{
get { return _selectedUser; }
set
{
if (_selectedUser != value)
{
_selectedUser = value;
RaisePropertyChanged();
}
}
}
...
}
我想以下列方式(或任何类似的方式)显示SelectedUser
角色:
<Window.DataContext>
<vm:UserManagerViewModel/>
</Window.DataContext>
<ListBox ItemsSource="{Binding AllRoles}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" IsChecked="{Binding ???}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
我需要设置IsChecked
的{{1}}属性,以便它代表CheckBox
个角色?
答案 0 :(得分:1)
假设您要“检查”SelectedUser
所拥有的角色。
首先我们回答这个问题,“这取决于哪些数据?”答案很简单,这取决于角色本身,所以我们写道:
<CheckBox Content="{Binding Name}" IsChecked="{Binding .}"/>
现在显然,这不是一个博尔;所以我们需要为它编写一个转换器来检查集合。我们可以在这里做一个MultiValueConverter(如在@Moji的回答中),但是通过依赖属性公开集合可能更容易,并且在创建转换器时绑定。
<Window.Resources>
<local:CollectionContainsConverter Collection="{Binding SelectedUser.Roles}"/>
</Window.Resources>
<CheckBox Content="{Binding Name}" IsChecked="{Binding Path=., Converter={StaticResource CollectionContainsConverter}"/>
转换器:
public class CollectionContainsConverter : IValueConverter
{
public IEnumerable<object> Collection { get; set; } //This is actually a DP
public object Convert(...)
{
return Collection.Contains(value);
// or possibly, to allow for the Object.Equals override
return Collection.Any(o => o.Equals(value));
}
public object ConvertBack(...)
{
return Binding.DoNothing;
}
}
如果没有对此进行测试,您可能需要使用第二个返回值,因此它不会比较引用,并使用Object.Equals
(或您选择的其他比较器)来确定项目是否在列表中。
答案 1 :(得分:0)
您可以使用MultipleBinding和MultipleValueVonverter,如下所示
<Grid>
<Grid.Resources>
<local:RoleValueConverter x:Key="converter"></local:RoleValueConverter>
</Grid.Resources>
<ListBox ItemsSource="{Binding AllRoles}" >
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" >
<CheckBox.IsChecked>
<MultiBinding Converter="{StaticResource converter}">
<Binding Path="."></Binding>
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ListBox}}" Path="DataContext"></Binding>
</MultiBinding>
</CheckBox.IsChecked>
</CheckBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
public class RoleValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
//values[0] is Role object
//value[1] is UserManagerViewModel
// then you can see if Selected user had Role object return true else return false
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}