C# WPF惰性绑定上下文菜单项源
我成功地将C# WPF惰性绑定上下文菜单项源,c#,wpf,mvvm,contextmenu,caliburn.micro,C#,Wpf,Mvvm,Contextmenu,Caliburn.micro,我成功地将MenuModel绑定到MenuItem.itemsource。然而,这些项目应该是情境化的。现在,我填充了ViewModel集合,数据已经准备好绑定到源项,但这并没有涵盖我的所有场景 当上下文菜单打开时,我需要重新填充ViewModel集合,也就是说,我的目标是只在上下文菜单打开时填充集合,因为前面的内容没有意义(项目应该由ListBox SelectedItem上下文化) XAML <Style x:Key="ActionMenuItemStyle" TargetType="
MenuModel
绑定到MenuItem.itemsource
。然而,这些项目应该是情境化的。现在,我填充了ViewModel集合,数据已经准备好绑定到源项,但这并没有涵盖我的所有场景
当上下文菜单打开时,我需要重新填充ViewModel集合,也就是说,我的目标是只在上下文菜单打开时填充集合,因为前面的内容没有意义(项目应该由ListBox SelectedItem上下文化)
XAML
<Style x:Key="ActionMenuItemStyle" TargetType="MenuItem" BasedOn="{StaticResource MetroMenuItem}">
<Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}" />
<Setter Property="Icon" Value="{StaticResource ActionMenuItemIcon}" />
<Setter Property="IsCheckable" Value="{Binding IsCheckable, Mode=OneWay}" />
<Setter Property="IsChecked" Value="{Binding IsChecked, Mode=OneWay}" />
<Setter Property="Command" Value="{Binding Action}" />
<Setter Property="CommandParameter" Value="{Binding ActionParameter}" />
</Style>
<HierarchicalDataTemplate DataType="{x:Type model:MenuModel}" ItemsSource="{Binding Children}">
<MenuItem Header="{Binding Path=Header}" Style="{StaticResource ActionMenuItemStyle}"
UsesItemContainerTemplate="True" ItemContainerTemplateSelector="{StaticResource ActionMenuItemContainerTemplateSelector}"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type model:SeparatorMenuModel}">
<Separator Style="{StaticResource {x:Static MenuItem.SeparatorStyleKey}}"/>
</DataTemplate>
<ContextMenu x:Key="OneItem">
<MenuItem Header="{x:Static resx:StudioResources.Advanced}">
<MenuItem Header="{x:Static resx:StudioResources.MoveToRoutineMenu}"
ItemsSource="{Binding PlacementTarget.Tag.Routines, RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}}"
UsesItemContainerTemplate="True"
ItemContainerTemplateSelector="{StaticResource ActionMenuItemContainerTemplateSelector}"/>
</MenuItem>
</ContextMenu>
视图模型
public IObservableCollection<IMenuModel> Routines { get; private set; }
protected override void OnViewLoaded(object view)
{
base.OnViewLoaded(view);
GetParent().Routines.CollectionChanged += (s, e) =>
{
Routines.Clear();
var names = GetParent().Routines.Where(r => r != GetParent().ActiveRoutine).Take(5).OrderBy(r => r);
var menus = names.Select(name => new MenuModel(name, new MenuAction<string>(MoveToRoutine), name)).ToList();
menus.ForEach(m => m.WithEditor(GetParent()));
Routines.AddRange(menus);
};
}
public IObservableCollection例程{get;private set;}
加载视图时受保护的覆盖无效(对象视图)
{
base.OnViewLoaded(视图);
GetParent().Routines.CollectionChanged+=(s,e)=>
{
例程。清除();
var name=GetParent().Routines.Where(r=>r!=GetParent().ActiveRoutine).Take(5).OrderBy(r=>r);
var menus=names.Select(name=>newmenumodel(name,newmenuaction(MoveToRoutine),name)).ToList();
menus.ForEach(m=>m.WithEditor(GetParent());
例程。添加范围(菜单);
};
}
我听一个事件来重新填充集合,但实际上我需要听几个其他事件,我想知道是否有一种干净的方法,比如在上下文菜单打开时填充。只需绑定集合即可。您是说子菜单中的项目将根据
列表框的不同而变化。选择editem
?在这种情况下,请在ListBox.SelectedItem
changes时重新填充集合。如果您坚持要使此操作尽可能困难且容易出错,请处理上下文菜单所有者的上下文菜单打开
,并在代码隐藏中执行所有操作。当列表框时,项目将更改。选择EdItem
更改,是的,但还有其他事件会影响菜单项,这就是为什么我只想在开始时填充。这样,我只会在需要时调用Clear
和AddRange
(这是一个繁重的操作)。您有多少菜单项?不多,但应用程序很大(它是一个IDE),因此无用的UI事件传播得更好,ContextMenuOpening
在每次菜单即将打开时都会引发,没有其他时间,所以这听起来像是一个好地方,可以做任何你想在那个时候发生的事情,而且只有那个时候。只需绑定一个集合。您是说子菜单中的项目将根据列表框的不同而变化。选择editem
?在这种情况下,请在ListBox.SelectedItem
changes时重新填充集合。如果您坚持要使此操作尽可能困难且容易出错,请处理上下文菜单所有者的上下文菜单打开
,并在代码隐藏中执行所有操作。当列表框时,项目将更改。选择EdItem
更改,是的,但还有其他事件会影响菜单项,这就是为什么我只想在开始时填充。这样,我只会在需要时调用Clear
和AddRange
(这是一个繁重的操作)。您有多少菜单项?不多,但应用程序很大(它是一个IDE),因此无用的UI事件传播得更好,ContextMenuOpening
在每次菜单即将打开时都会引发,在没有其他时间,所以这听起来像是一个好地方做任何你想发生的事情,然后只有那时。