繁体   English   中英

如何将 mdiContainer 子项绑定到 viewModel 属性?

[英]How to bind mdiContainer children to viewModel property?

我正在为我的 WPF 应用程序使用 CodePlex wpfmdi 容器。

我需要将MdiContainer的孩子绑定到 viewModel 属性。

<mdi:MdiContainer Name="Container" Grid.Row="1" Background="GhostWhite" Children="{Binding Path=Container}"/>

如果我这样做,我会收到此错误:

'System.Windows.Data.Binding' 类型的 Object 无法转换为'System.Collections.ObjectModel.ObservableMFChild'1 类型

这是MdiContainer中的Children属性的样子:

public ObservableCollection<MdiChild> Children { get; set; }

我究竟做错了什么?

Children属性不作为依赖属性公开,这意味着您无法绑定它。 此外,它在MdiContainer类型的构造函数中初始化一次,然后将处理程序添加到底层ObservableCollection<MdiChild>CollectionChanged事件。 它永远不会更新或删除。

因此,虽然Children属性有一个 setter,但如果您使用它来设置不同的集合,它将破坏控件。 这也意味着您不能简单地创建附加属性来公开可绑定的Children依赖项属性。

除此之外, MdiChild是一个Control ,因此它实际上与您查看 model 的目的相矛盾。 如果您从视图 model 公开一组用户界面控件,则这与 MVVM 模式冲突。 视图模型不应该对视图有任何了解。 但是,MDI 控件似乎没有遵循自定义控件通常的 WPF 做法,因此这里没有太大的改进空间,不支持数据模板, MdiContainer是一个UserControl ,依赖属性非常有限。

如果您真的想继续使用当前方法使用此控件,您可以:

  • 创建自定义附加行为以将您的视图 model 集合与MdiContainerChildren集合同步,反之亦然,请参阅WPF 中的 XAML 行为

  • 使用Loaded事件将Children集合分配给您的视图 model 属性。

     <mdi:MdiContainer Name="Container" Grid.Row="1" Background="GhostWhite" Loaded="MdiContainer_OnLoaded">
     private void MdiContainer_OnLoaded(object sender, RoutedEventArgs e) { var mdiContainer = (MdiContainer)sender; var dataContext = (Main)mdiContainer.DataContext; if (dataContext == null) return; dataContext.Children = mdiContainer.Children; }
  • Loaded事件使用EventTrigger ,并使用设置Children集合的自定义触发器操作。 这只是先前方法的不同变体,不需要代码隐藏。

    The new XAML behaviors for WPF package, which replaces the legacy Blend behaviors from the System.Windows.Interactivity namespace already includes such a trigger action. 安装Microsoft.Xaml.Behaviors.Wpf NuGet ZEFE90A8E604A77640E8ZD03 和使用这个:

     <mdi:MdiContainer Name="Container" Grid.Row="1" Background="GhostWhite"> <behaviors:Interaction.Triggers> <behaviors:EventTrigger EventName="Loaded"> <behaviors:ChangePropertyAction TargetObject="{Binding DataContext, ElementName=Container}" PropertyName="Children" Value="{Binding Children, ElementName=Container}"/> </behaviors:EventTrigger> </behaviors:Interaction.Triggers> </mdi:MdiContainer>

请注意,使用这些方法,您可以同步到自己的集合,也可以直接使用传递给视图 model 的MdiContainer的集合。 这些只是解决方法。 如果您想以干净且符合 MVVM 的方式实现此功能,我认为您需要扩展或修复控件本身,这是相当昂贵且不推荐的,因为它似乎已经死了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM