C# 以某种方式通知转换器集合已更改
这个转换器是我的间接问题,或者特别是其中的ObservableCollection用户_模块。此转换器连接到一组按钮 当我的应用程序启动时,集合为空,所有按钮均被禁用,然后当用户登录时,将填充该集合。但是,不会通知视图和viewmodel集合已更改,按钮在不应更改时仍处于禁用状态。我该怎么做 我相信下面三段代码是可以的,但我不确定第四段,我相信这是我需要修改的地方C# 以某种方式通知转换器集合已更改,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,这个转换器是我的间接问题,或者特别是其中的ObservableCollection用户_模块。此转换器连接到一组按钮 当我的应用程序启动时,集合为空,所有按钮均被禁用,然后当用户登录时,将填充该集合。但是,不会通知视图和viewmodel集合已更改,按钮在不应更改时仍处于禁用状态。我该怎么做 我相信下面三段代码是可以的,但我不确定第四段,我相信这是我需要修改的地方 public class IsEnabledMultiValueConverter : IMultiValueConverter {
public class IsEnabledMultiValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
try
{
bool userHasAccess = false;
int Module_ID = (int)values[0];
ObservableCollection<UserModuleLevel> user_module_levels = values[1] as ObservableCollection<UserModuleLevel>;
UserModuleLevel userModuleLevel = user_module_levels.SingleOrDefault(um => um.Module_ID == Module_ID);
if (userModuleLevel != null)
{
userHasAccess = true;
}
return (userHasAccess);
}
catch
{
return false;
}
}
公共类IsEnabledMultiValueConverter:IMMultivalueConverter
{
公共对象转换(对象[]值,类型targetType,对象参数,System.Globalization.CultureInfo区域性)
{
尝试
{
bool userHasAccess=false;
int模块_ID=(int)值[0];
ObservableCollection用户\模块\级别=值[1]作为ObservableCollection;
UserModuleLevel UserModuleLevel=user\u module\u levels.SingleOrDefault(um=>um.module\u ID==module\u ID);
if(userModuleLevel!=null)
{
userHasAccess=true;
}
返回(userHasAccess);
}
抓住
{
返回false;
}
}
我的XAML:
<Button.IsEnabled>
<MultiBinding Converter="{StaticResource converter}" >
<Binding Path="Module_ID" />
<Binding Path="DataContext.UserModuleCollection"
RelativeSource="{RelativeSource AncestorType=Window}" />
</MultiBinding>
</Button.IsEnabled>
My ViewModel:一旦用户登录UserModuleLevel并填充_current_user
public ObservableCollection<UserModuleLevel> UserModuleCollection
{
get { return CurrentUser._current_user.UserModuleLevels; }
}
公共ObservableCollection用户模块Collection
{
获取{return CurrentUser.\u current\u user.UserModuleLevels;}
}
保存集合的用户类:
public class User
{
public User(){}
public int User_ID { get; set; }
public string Name { get; set; }
public ObservableCollection<UserModuleLevel> UserModuleLevels = new ObservableCollection<UserModuleLevel>();
}
公共类用户
{
公共用户(){}
公共int用户_ID{get;set;}
公共字符串名称{get;set;}
public ObservableCollection UserModuleLevel=新ObservableCollection();
}
填充可观察集合时,转换器的Convert
方法将不会执行。这是因为只有项控件,如ListBox
或ComboBox
侦听INotifyCollectionChanged
接口的CollectionChanged
事件。但这不适用于为你解决这个问题
如果我正确理解了您的代码,我建议您创建一个新的ViewModel类,该类将为每个按钮实例化。在该类中,您指定模块ID以及用户是否能够使用它(您当前在转换器中执行的检查)。将每个按钮绑定到该视图模型的新实例
我希望这会有所帮助。如果您有任何问题,请留下评论。有两点可能是原因。您说用户何时登录ModuleLevel? 那么最初CurrentUser和后续模块级别将为空? 设置Currentuser及其UserModuleLevel时,可能需要引发通知事件 此外,在第四节中,您将th private变量设置为new,但该属性也有一个setter,没有通知事件。如果随后要设置该属性,则需要实现INotifyPropertyChanged。或者通过删除setter使其只读
public class User:INotifyPropertyChanged
{
public User(){}
public int User_ID { get; set; }
public string Name { get; set; }
private ObservableCollection<UserModuleLevel> user_module_levels = new ObservableCollection<UserModuleLevel>();
public ObservableCollection<UserModuleLevel> UserModuleLevels
{
get
{ return user_module_levels; }
set
{
user_module_levels = value;
this.OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
公共类用户:INotifyPropertyChanged
{
公共用户(){}
公共int用户_ID{get;set;}
公共字符串名称{get;set;}
私有ObservableCollection用户\模块\级别=新ObservableCollection();
公共ObservableCollection用户模块级别
{
得到
{返回用户\模块\级别;}
设置
{
用户\模块\级别=值;
this.OnPropertyChanged();
}
}
公共事件属性更改事件处理程序属性更改;
[NotifyPropertyChangedInvocator]
受保护的虚拟void OnPropertyChanged([CallerMemberName]字符串propertyName=null)
{
PropertyChangedEventHandler处理程序=PropertyChanged;
if(处理程序!=null)
{
处理程序(这是新的PropertyChangedEventArgs(propertyName));
}
}
}
我不确定您想在这里实现什么,但我能得到的是,您希望在列表中添加或删除项目时调用转换器
如果是这种情况,您可以在多重绑定下在XAML中使用另一个绑定,该绑定将与ObservableCollection的Count
绑定。每当添加/删除项目时,Count
将被更新。因此,您只需得到通知即可
<Button.IsEnabled>
<MultiBinding Converter="{StaticResource converter}" >
<Binding Path="Module_ID" />
<Binding Path="DataContext.UserModuleCollection"
RelativeSource="{RelativeSource AncestorType=Window}" />
<Binding Path="DataContext.UserModuleCollection.Count" <-- Only to refresh
RelativeSource="{RelativeSource AncestorType=Window}" />
</MultiBinding>
</Button.IsEnabled>
您没有以适当的方式使用转换器。您要做的是使用CanExecute
方法在按钮上设置命令。