gpt4 book ai didi

c# - 如果字典填充较晚,则绑定(bind)无法与字典一起使用

转载 作者:行者123 更新时间:2023-12-03 10:54:41 24 4
gpt4 key购买 nike

我有一个 WPF 应用程序。我正在使用 MVVM 模式。我有一本字典:

 public abstract class ViewModelBase
{
public static Dictionary<string, Action> Permissions { get; set; }

...
}

我想将它的值绑定(bind)到菜单项的可见性,如下所示:
<MenuItem x:Name="systemMenuItem" Header="System" Visibility="{Binding Permissions[systemMenuItem].CanBeShow, Converter={StaticResource BoolToVis}}">...</MenuItem>

为了填充这个字典,我需要窗口构建可视化树,因为字典的元素包含来自窗口 MenuItem 的信息。如果我将在 InitializeComponent 之前创建字典,我将得到一个异常,即没有值为 systemMenuItem 的键因为 VisualTreeHelper.GetChildrenCount返回零个元素。如果我会在 Loaded 上做事件我将获得正常填充的字典,但在这种情况下绑定(bind)不起作用。如何在向用户显示窗口并从 MenuItems 获取信息之前填写我的字典?在这种情况下,我怎样才能使我的绑定(bind)工作?该窗口是主要和启动。

最佳答案

作为一般规则使用字典进行绑定(bind)是一个坏主意,这可能是为什么 MS 从未将 Observable Dictionary 创建为 .Net 框架的一部分,你最好的办法是创建一个 Permission 类,然后拥有它们的 Observable Collection ,这将为您提供权限上的集合绑定(bind)和更改绑定(bind)

注意:这里使用 C#6,所以如果您使用的是早期版本,您可能需要对其进行调整

例子

Xaml

<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</Window.Resources>
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<DockPanel>
<Menu DockPanel.Dock="Top" ItemsSource="{Binding Permissions}">
<Menu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Header" Value="{Binding Name}"/>
<Setter Property="Visibility" Value="{Binding CanBeShow, Converter={StaticResource BooleanToVisibilityConverter}}"/>
<Setter Property="Command" Value="{Binding Action}"/>
</Style>
</Menu.ItemContainerStyle>
</Menu>
<Grid/>
</DockPanel>
</Window>

查看模型
public class ViewModel
{
public ViewModel()
{
//some dummy data
Permissions.Add(new Permission()
{
Name = "Open",
CanBeShow = true,
Action = ApplicationCommands.Open
});
Permissions.Add(new Permission()
{
Name = "Save",
CanBeShow = false,
Action = ApplicationCommands.Save
});
Permissions.Add(new Permission()
{
Name = "Delete",
CanBeShow = true,
Action = ApplicationCommands.Delete
});
}

public ObservableCollection<Permission> Permissions { get; } = new ObservableCollection<Permission>();
//notice no set you want to change the content of the collection not the collection
}

public class Permission:INotifyPropertyChanged
{
private string name;

public string Name
{
get { return name; }
set
{
name = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
}
}

private bool canBeShow;

public bool CanBeShow
{
get { return canBeShow; }
set
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CanBeShow)));
canBeShow = value;
}
}


private ICommand action;
public ICommand Action
{
get { return action; }
set {
action = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Action)));
}
}

public event PropertyChangedEventHandler PropertyChanged;
}

但是,如果您尝试对菜单操作实现某种安全性,
那么这样做的首选方法是覆盖 ICommand 以创建一个自定义命令,该命令将查找它自己的权限并将它们公开为属性而不靠近 View
public class PermissionCommand:INotifyPropertyChanged,ICommand
{
public event EventHandler CanExecuteChanged;
public event PropertyChangedEventHandler PropertyChanged;

private string name;

public string Name
{
get { return name; }
set
{
name = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
}
}

public bool CanBeShow
{
get
{
//Check permissions for CanBeShow here
}
}

public bool CanExecute(object parameter)
{
//Check permissions for Execution here
}

public void Execute(object parameter)
{
// perform action here
}
//you will need to trigger the events when the permissions change
}

关于c# - 如果字典填充较晚,则绑定(bind)无法与字典一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39351100/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com