想象一下: 您有许多控件,您想要一个上下文菜单,相同的菜单。该上下文菜单将是动态的,可以随时更改。所以你创建一个这样的静态类:
public static class EmployeeContextMenu
{
private static ContextMenu EmployeeMenu { get; set; }
static EmployeeContextMenu()
{
EmployeeMenu = new ContextMenu();
}
public static ContextMenu Get()
{
return EmployeeMenu;
}
public static void Set(List<String> employees)
{
EmployeeMenu = new ContextMenu();
MenuItem mi;
foreach (var item in employees)
{
mi = new MenuItem();
mi.Header = item;
EmployeeMenu.Items.Add(mi);
}
}
}
在某些时候你需要更改菜单项并使用上面的Set方法,效果非常好。 不知何故,您想将控件上下文菜单绑定到Get方法。 可能会像:
<Window.Resources>
<ObjectDataProvider ObjectType="{x:Type local:EmployeeContextMenu}" MethodName="Get" x:Key="myCM" />
</Window.Resources>
<Grid>
<TextBlock Name="tb" ContextMenu="{Binding Source={StaticResource myCM}}" />
</Grid>
当然,您希望在调用静态Set方法后立即更新控件上下文菜单。
但是上面,绑定基本上是错误的......根本没有显示上下文菜单。 那么你将如何设置绑定? Datacontext,datasource?在哪里以及如何?
如果你实施
,它当然会有用tb.ContextMenu = EmployeeContextMenu.Get();
但是,如果您有一个未知数量的动态创建的用户控件,那么这将是一个糟糕的解决方案,您非常希望拥有将在动态更新的上述上下文菜单。
答案 0 :(得分:0)
您可以做的是重新构建它,因为change notification
属性需要EmployeeMenu
才能在Set()
方法之后进行更新
所以从课程本身开始
namespace CSharpWPF
{
public sealed class EmployeeContextMenu : INotifyPropertyChanged
{
private EmployeeContextMenu()
{
//prevent init
}
static EmployeeContextMenu()
{
Instance = new EmployeeContextMenu();
Instance.EmployeeMenu = new ContextMenu();
}
public static EmployeeContextMenu Instance { get; private set; }
private ContextMenu _menu;
public ContextMenu EmployeeMenu
{
get
{
return _menu;
}
set
{
_menu = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("EmployeeMenu"));
}
}
public void Set(List<String> employees)
{
EmployeeMenu = new ContextMenu();
MenuItem mi;
foreach (var item in employees)
{
mi = new MenuItem();
mi.Header = item;
EmployeeMenu.Items.Add(mi);
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
我已实施INotifyPropertyChanged
使用私有构造函数使其非静态以避免init
密封班级以防止进一步推进
添加静态Instance
属性以从xaml
休息是非常基本的
XAML
<Grid xmlns:l="clr-namespace:CSharpWPF">
<TextBlock Name="tb" ContextMenu="{Binding EmployeeMenu,Source={x:Static l:EmployeeContextMenu.Instance}}" />
</Grid>
调用Set()方法
EmployeeContextMenu.Instance.Set(list);
所以整个想法是在保持静态引用的同时启用属性更改通知