【问题标题】:UI is not updated when value of ObservableCollection Changes当 ObservableCollection 的值更改时 UI 不会更新
【发布时间】:2014-03-02 21:35:46
【问题描述】:

我有一个名为 MainWindow.xaml 的窗口和一个名为 Tiles.xaml 的页面。

Window 和 Page 共享同一个 ViewModel,称为 MainWindowViewModel.cs

这里是 MainWindowViewModel.cs

public class MainWindowViewModel : MainViewModel
{
    public MainWindowViewModel()
    {
        ERP_Lite_ServiceClient client = new ERP_Lite_ServiceClient();

        Parents = new ObservableCollection<MenuItemDTO>(client.GetAllMenuItems().Where(m => m.ParentID == null));

        if (SelectedParent != null)
        {
            Children = new ObservableCollection<MenuItemDTO>(client.GetAllMenuItems().Where(m => m.ParentID == SelectedParent.MenuItemID));
        }

        client.Close();

    }

    private ObservableCollection<MenuItemDTO> _parents;
    public ObservableCollection<MenuItemDTO> Parents
    {
        get
        {
            return _parents;
        }
        set
        {
            _parents = value;
            OnPropertyChanged("Parents");
        }
    }

    private ObservableCollection<MenuItemDTO> _children;
    public ObservableCollection<MenuItemDTO> Children
    {
        get
        {
            return _children;
        }
        set
        {
            _children = value;
            OnPropertyChanged("Children");
        }
    }

    private MenuItemDTO _selectedParent;
    public MenuItemDTO SelectedParent
    {
        get
        {
            return _selectedParent;
        }
        set
        {
            _selectedParent = value;
            OnPropertyChanged("SelectedParent");

            ERP_Lite_ServiceClient client = new ERP_Lite_ServiceClient();
            Children = new ObservableCollection<MenuItemDTO>(client.GetAllMenuItems().Where(m => m.ParentID == SelectedParent.MenuItemID));
            client.Close();
        }
    }

}

这里是 MainWindow.xaml

<Window.........>
    <Window.DataContext>
        <loc:MainWindowViewModel />
    </Window.DataContext>

    <Grid>

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

        <Grid Grid.Row="0" Background="#FF2A2A2A">

            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="50" />
                <ColumnDefinition Width="50" />
            </Grid.ColumnDefinitions>

            <ListBox Grid.Column="0" ItemsSource="{Binding Parents}" DisplayMemberPath="Title"
                     SelectedItem="{Binding SelectedParent}"
                     Height="35" FontSize="18" BorderThickness="0" Background="#FF2A2A2A" Foreground="White" SelectedIndex="0">

                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel IsItemsHost="True" Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>


                <ListBox.Resources>
                    <Style TargetType="{x:Type ListBoxItem}">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                                                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                                                      VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
                        <Setter Property="Margin" Value="5,0" />
                        <Style.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter Property="Foreground" Value="#FF1CB4F7" />
                                <Setter Property="FontWeight" Value="SemiBold" />
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Foreground" Value="#FF87CEEB" />
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </ListBox.Resources>

            </ListBox>

        </Grid>

        <Frame Grid.Row="1" Source="/WPF_Client;component/Pages/Tiles.xaml"/>

    </Grid>

</Window>

这是 Tiles.xaml

<Page.....>

    <Page.DataContext>
        <self:MainWindowViewModel />
    </Page.DataContext>

    <ListBox ItemsSource="{Binding Children}" DisplayMemberPath="Title">


    </ListBox>

</Page>

我认为我已经在 MainWindowViewModel.cs 上正确实现了 INotifyPropertyChanged。我也使用 ObservableCollection 作为 Children 属性。但是我还是不明白为什么当Children中的集合发生变化时UI没有得到通知。

【问题讨论】:

    标签: c# wpf xaml mvvm


    【解决方案1】:

    您已在 xaml 中创建了两个 MainWindowViewModel 实例。从 Tiles.xaml 中删除 MainWindowViewModel

    【讨论】:

    • 谢谢 我在 App.xaml 中创建了一个 ViewModel 实例,并在 Window 和 Page 上都引用了它。现在它工作正常。再次感谢您在我的代码中提及错误。
    • @Vishal 似乎Frame(此处为Page)的内容并不是真正设计为继承其父框架的DataContext。所以你可能不得不做类似here描述的事情。
    猜你喜欢
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 2018-05-18
    • 2014-01-01
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多