【问题标题】:Access my Views from bound ItemsControl从绑定的 ItemsControl 访问我的视图
【发布时间】:2010-09-01 09:27:40
【问题描述】:

我有一个典型的 MVVM 场景:我有一个 ItemsControl 绑定到 StepsViewModels 的 ObservableCollection。我定义了一个 DataTemplate,以便将 StepViewModels 呈现为 StepViews。在 StepView 中也会发生同样的情况:我有一个 ItemsControl 到一个 ObservableCollection 的 ParameterViewModels 和一个 DataTemplate 来将它们呈现为 ParameterViews。

我的问题是:我必须刷新 ItemsControl 才能呈现添加的项目和删除项目。我可以使用 StepViews 刷新ItemsControl,因为我可以访问它并且可以调用 ItemsControl.Items.Refresh()。但是如何访问 StepViews 以便调用 Refresh 方法? ItemsControl Items 是 StepViewModels...

代码如下:

<UserControl x:Class="mylib.EditorView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:my="clr-namespace:mylib">
    <UserControl.Resources>
        <DataTemplate DataType="{x:Type my:StepViewModel}">
            <my:StepView HorizontalAlignment="Stretch"/>
        </DataTemplate>
    </UserControl.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="27"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <ScrollViewer VerticalScrollBarVisibility="Auto" Grid.Row="1" VerticalAlignment="Top">
            <StackPanel Orientation="Vertical">
                <TextBlock Name="lblHelpRefresh" Margin="0 7 0 7" Visibility="{Binding HelpVisible}"
                       VerticalAlignment="Center" HorizontalAlignment="Center"
                       FontSize="9pt"  Foreground="#949494"
                       Text="Please click refresh to reload this list"/>
                <ItemsControl Name="stkStepContent" 
                          ItemsSource="{Binding Steps}"/>
            </StackPanel>
        </ScrollViewer>
    </Grid>
</UserControl>

如何访问呈现 stkStepContent 项的 StepView 控件?

【问题讨论】:

  • 如果你使用 ObservableCollections 通常不需要显式刷新;绑定检测集合何时更改并自行更新。
  • 我很确定ItemsControl 需要显式刷新来更新渲染。 ItemsControl ItemsSource 绑定到 ObservableCollection 并且需要刷新。
  • 正如 Alex 所说 - 如果您使用的是 ObservableCollection,则不需要刷新。
  • 那么,有什么东西会导致 ItemsControl 不更新吗?
  • StepViewModel 是否包含第二个 ObservableCollection,其中包含您尝试刷新的项目?如果是这样,您可以连接一个 PropertyChanged 事件,以便当内部 ObservableCollection 更新时,它会在 StepViewModel 上触发 PropertyChanged 通知。

标签: c# .net wpf mvvm itemscontrol


【解决方案1】:

如果您有 ObservableCollection,那么添加和删除项目应该会自动刷新。但是,如果您刚刚更新了 StepsViewModel 中的一个属性,那么 StepsViewModel 应该是通过实现 INotifyPropertyChanged 接口或从 DependencyObject 继承并改用 Dependency 属性来提醒更新的那个。

无论如何,如果您真的希望能够手动刷新您的集合,请在您的 ViewModel 中使用 CollectionViewSource。然后调用 CollectionViewSource 的 View.Refresh() 方法。

【讨论】:

    【解决方案2】:

    要在代码隐藏中访问您的视图,您可以使用控件的 DataContext 并将其转换为适当的视图。例如:

    ObservableCollection<StepViewModel> vmCollection = 
        stkStepContent.DataContext as ObservableCollection<StepViewModel>;
    
    foreach(StepViewModel vm in vmCollection)
    {
        vm.Refresh();
    }
    

    编辑:StepViewModel 是否包含第二个 ObservableCollection,其中包含您尝试刷新的项目?如果是这样,您可以连接一个 PropertyChanged 事件,以便当内部 ObservableCollection 更新时,它会触发 StepViewModel 上的 PropertyChanged 通知

    【讨论】:

    • 我将此答案标记为已接受,但您的评论真正解决了我的问题。添加到 ObservableCollection 时,我没有调用 OnPropertyChanged。相当愚蠢的错误。
    • 编辑了我的答案以包含您所指的评论。在写这个答案时,我实际上打算添加那个问题,但我想我会把它作为评论而不是因为它是一个问题而不是一个答案:)
    猜你喜欢
    • 1970-01-01
    • 2021-03-16
    • 1970-01-01
    • 2014-09-24
    • 2011-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多