【问题标题】:WPF => Binding ContextMenu with CollectionViewSourceWPF => 将 ContextMenu 与 CollectionViewSource 绑定
【发布时间】:2017-07-27 17:47:08
【问题描述】:

为什么会这样:

<Button x:Name="btnCritereAdd" Content="{Binding Source={x:Static resx:resMain.lblCriterAdd}}" Style="{StaticResource btnStandardClr}" Click="btnMenuPopup_Click" ContextMenuService.Placement="Bottom">
    <Button.ContextMenu>
        <ContextMenu x:Name="cmuCriteres">
            <ContextMenu.ItemsSource>
                <Binding Path="CriteresDispo" />
            </ContextMenu.ItemsSource>
            <ContextMenu.InputBindings>
                <MouseBinding MouseAction="LeftClick" Command="" />
            </ContextMenu.InputBindings>
        </ContextMenu>
    </Button.ContextMenu>
</Button>

但不是这个:

<Button x:Name="btnCritereAdd" Content="{Binding Source={x:Static resx:resMain.lblCriterAdd}}" Style="{StaticResource btnStandardClr}" Click="btnMenuPopup_Click" ContextMenuService.Placement="Bottom">
    <Button.ContextMenu>
        <ContextMenu x:Name="cmuCriteres">
            <ContextMenu.Resources>
                <CollectionViewSource x:Key="cvsCriteres" Source="{Binding CriteresDispo}"/>
            </ContextMenu.Resources>
            <ContextMenu.ItemsSource>
                <Binding Source="{StaticResource cvsCriteres}" />
            </ContextMenu.ItemsSource>
            <ContextMenu.InputBindings>
                <MouseBinding MouseAction="LeftClick" Command="" />
            </ContextMenu.InputBindings>
        </ContextMenu>
    </Button.ContextMenu>
</Button>

我在 CodeBehind 中的 Button 上设置了 DataContext:

btnCritereAdd.DataContext = vmFiltresChamps;

我在这两种情况下尝试使用“UpdateSourceTrigger=PropertyChanged”和“NotifyOnSourceUpdated=True”,但没有任何变化。 列表为空...

你有什么想法吗?

虚拟机端: 属性:

public ItemCollection CriteresDispo { get { return _CriteresDispo; } set { _CriteresDispo = value; RaisePropertyChanged(nameof(CriteresDispo)); } }

后面的代码调用的命令

public RelayCommand<ItemCollection> LoadCriteresCommand { get; set; }

private void LoadCriteres(ItemCollection obj) {
        var ht = new tblFiltreChamps();
        Classes.clsUtils.GetFiltresSel(obj, ht);
        CriteresDispo = new ItemsControl().Items;
        if (ht.items.Count > 0) {
            foreach (var item in ht.items.OrderBy((x) => x.Desc).ToList()) {
                var mi = new MenuItem() { Header = item.Desc, Tag = item };
                mi.Command = AddCritereCommand;
                mi.CommandParameter = item;
                CriteresDispo.Add(mi);
            }
        }
        if (CriteresAddAction != null) CriteresAddAction();
}

【问题讨论】:

  • 尝试将 CollectionViewSource 移动到按钮资源,资源查找在可视化树上,水平查找可能会变得奇特,无法检查输出窗口是否存在绑定错误
  • 您好 MikeT,我已经尝试将它放入 button.resource 中,但没有任何改变。什么是水平查找?
  • 横向查找正在查找定义在可视化树同一级别的资源
  • 我在输出中有这条消息:“System.Windows.Data 错误:5:BindingExpression 产生的值对目标属性无效。;Value='System.Windows.Controls.ItemCollection' BindingExpression: Path=CriteresDispo; DataItem='ViewModelFiltresChamps' (HashCode=6263136); 目标元素是 'CollectionViewSource' (HashCode=56403320); 目标属性是 'Source' (type 'Object')" 供参考,CriteresDispo 是 ItemCollection 类型
  • 错误表明问题是Source="{Binding CriteresDispo}",因为它是一个 CollectionViewSource 尝试 Source="{Binding CriteresDispo.View}" 代替

标签: c# wpf xaml binding


【解决方案1】:

CollectionViewSource 没有实现IEnumerable,因此不能设置为ContextMenuItemsSource 属性,它是IEnumerable 类型。

因此你需要改变:

<ContextMenu.ItemsSource>
    <Binding Source="{StaticResource cvsCriteres}"/>
</ContextMenu.ItemsSource>

收件人:

<ContextMenu.ItemsSource>
    <Binding Source="{StaticResource cvsCriteres}" Path="View"/>
</ContextMenu.ItemsSource>

这会将ItemsSource 设置为CollectionViewSourceView 属性,该属性的类型为CollectionView 并且确实实现IEnumerable

【讨论】:

    【解决方案2】:

    你有什么想法吗?

    绑定到StaticResource 时,当您为绑定到CollectonViewSourceSource 属性的属性引发PropertyChanged 事件时,目标属性不会得到更新。

    这就是区别。

    您需要绑定到一个属性,并为该特定属性引发PropertyChanged 事件,以使ItemsSource 集合得到刷新。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-09
      • 2011-04-04
      • 1970-01-01
      相关资源
      最近更新 更多