【问题标题】:Prerendering/hiding on load with WPF MVVM?使用 WPF MVVM 在加载时预渲染/隐藏?
【发布时间】:2015-12-15 14:29:45
【问题描述】:

我有一个用 WPF 编码的控件,它可以具有三个子元素之一 - 两个 SimpleChildElements 和一个 ComplexChildElement,比方说 - 并根据模型中的一些幕后逻辑在它们的显示之间交换我这样做。

<ItemsControl
   ItemsSource="{Binding ChildPanels.Values}" 
   Name="ContentControl1"
   >
   <ItemsControl.ItemTemplate>
     <DataTemplate>
       <ContentControl Content="{Binding}"
          Visibility="{Binding Path=Active, Converter={StaticResource BooleanToVisibilityConverter}}"/>
     </DataTemplate>
   </ItemsControl.ItemTemplate>
</ItemsControl>

子元素是它们自己的 ViewModel,我已经在上游声明了一些资源,因此它们有 DataTemplates。如果有帮助,我可以详细说明,但问题的关键在于:

当我在主控件中滚动元素时,ComplexChildElement 第一次弹出时,在它被装饰时会出现一个短暂的、几乎看不见的闪烁——它是一堆用 DevExpress 装饰的组合框。此设置意味着当我使用 ComplexChildElement 滚动记录并再次返回时不会闪烁,如果我在那里开始显示带有 ComplexChildElement 的主控件,则当它再次弹出时不会闪烁。

但是主控件被键控到另一个数据源,我不能保证第一条记录中会有一个 ComplexChildElement,它是由一个更大的显示框架在初始化时加载的,我真的不想在其中扎根目前。

那么我如何保证 ComplexChildElement 会在表单加载时呈现,并可能在之后立即隐藏它?我已经尝试过在此后面的函数中打开和关闭 ChildPanels.Active:

 <dxmvvm:Interaction.Triggers>
    <dxmvvm:EventToCommand EventName="Loaded" Command="{Binding OnViewLoadedCommand}" />
 </dxmvvm:Interaction.Triggers>

但这不会让它们渲染。

顺便说一句,那个函数:

foreach (var childModel in ChildPanels.Values)
  {
    childModel.Active = true;
    RaisePropertyChanged(() => childModel.Active);
  }
ChangeChildModel();

最后一个函数调用是在记录更改时更改子模型可见性的调用。如果我不做最后一次调用,所有子视图模型都开始可见。

【问题讨论】:

  • “我已经尝试过在这个后面的函数中打开和关闭 ChildPanels.Active:...但这并没有让它们渲染。”我认为这是预渲染视图的好地方。但为什么它根本不显示?
  • IDK,虽然我将功能添加到问题本身。当我在调试模式下运行并在函数中插入断点时,如果有帮助,我实际上看不到任何可见的 UI 元素。
  • ChangeChildModel() 有什么作用? :) 如果你正在处理它,你并没有真正预渲染它,对吧?
  • 只需根据当前选择的记录适当地设置 ChildModel.Active 来改变可见性。
  • 让子模型在加载时通​​知并处理自己的行为是否不谨慎?难道你不能把子模型放在一个可观察的集合中,当在集合中的一个子模型中调用 NotifyPropertyChanged 时,你会在父模型中为 Loaded 命令触发 RaisePropertyChanged 吗?

标签: c# wpf mvvm


【解决方案1】:

为什么不从一开始就将 Visibility 设置为 false?这并不妨碍您之后在 Active 上使用绑定。

绑定是可以的,但是因为它被DataTemplate用来修改可见性被父控件知道它是否应该呈现子控件。因此,根据 PropertyChanged 事件的订阅顺序,父控件可能会将控件视为可见,也可能不会。

顺便说一句,我想知道您的第一个目标是否不是防止在多个控件上调用 显示/隐藏 时可能发生的闪烁。我不确定预渲染是否是正确的解决方法。

根据闪烁的根本原因,已经有几个对 SO 的修复:

【讨论】:

    猜你喜欢
    • 2014-02-03
    • 2014-01-01
    • 2019-04-10
    • 2011-05-08
    • 2021-10-14
    • 2015-05-23
    • 2013-05-17
    • 2015-04-15
    • 1970-01-01
    相关资源
    最近更新 更多