Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF惰性绑定上下文菜单项源_C#_Wpf_Mvvm_Contextmenu_Caliburn.micro - Fatal编程技术网

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
在每次菜单即将打开时都会引发,在没有其他时间,所以这听起来像是一个好地方做任何你想发生的事情,然后只有那时。