更新ObservableCollection中的项目时,ItemsControl视图不会更新

时间:2014-06-24 10:28:13

标签: c# wpf mvvm observablecollection

简介

嗨,我在这里遇到一个奇怪的问题。如果我要更新模型,我的ItemsControl不会更新视图(例如更改IsSelected的值)。

IsSelected目的之一是,如果值为true,则MusicalNotationBox(UserControl)的背景将更改为蓝色,如果是{s} false然后它又变回透明了。

  

很多人问:为什么不使用 Focus 等触发器 IsSelected 因为它不仅仅是   为"视觉"目的。我有一个命令可以改变某些   每个Property的{​​{1}}(例如,注意事项的八度音阶)   VM MusicalNotation中的对象,MusicalNotations(支持   多选),所以我认为我在模型中需要IsSelected==true但这不是问题所在,所以请不要单独回答这个问题。

问题是:

  1. 模型属性已成功更改(已检查并已验证),但似乎视图不是
  2. 如果我使用UserControl的单数形式,例如IsSelected(ofc和它的朋友a.k.a VM中的正确属性),完全同步。所以,我不太确定OC的问题在哪里。
  3. 更新:例如,如果我创建一个MouseBinding,每次点击,然后添加到列表中的新<c:MusicalNotationBox DataContext={Binding}/>视图也会更新。
  4.   

    我已经在&#34; Observable Collection上阅读了几个主题(谷歌和这里)   没有更新ItemsControl`,但仍然没有找到令人满意的答案。

    这是我的代码(代码可能会为了清晰起见而修剪(...)):

    模型

    MusicalNotation

    查看模型

    public class MusicalNotation : ... INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        ...
        private bool _isSelected;
        ...
        public bool IsSelected
        {
            get { return _isSelected; }
            set { _isSelected = value; NotifyPropertyChanged("IsSelected"); }
        }
        ...
        public MusicalNotation()
        {
            ...
            IsSelected = false;
        }
        ...
        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    

    查看

    public class MainWindowModelView : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private ObservableCollection<MusicalNotation> _musicalNotations;
        ...
        public ObservableCollection<MusicalNotation> MusicalNotations
        {
            get { return _musicalNotations; }
            set { _musicalNotations = value; NotifyPropertyChanged("MusicalNotations"); }
        }
    
        public MainWindowModelView()
        {
            ...
            MusicalNotations = new ObservableCollection<MusicalNotation>();
    
            //Direct initialization for testing purpose
            MusicalNotations.Add(MusicalNotation.GetEmptyNote(new TimeSignature(4, 4)));
            MusicalNotations.Add(MusicalNotation.GetEmptyNote(new TimeSignature(4, 4)));
    
            foreach (MusicalNotation item in MusicalNotations)
            {
                item.IsSelected = true;
            }
        }
    
        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    感谢。

    UPDATE,My MusicalNotationBox XAML

    <Window ...>
    <Window.Resources>
    
    </Window.Resources>
    <Window.InputBindings>
        ...
    </Window.InputBindings>
    <Grid>
        ...        
        <ItemsControl Grid.Column="0" Grid.Row="0" ItemsSource="{Binding MusicalNotations, Mode=OneWay}"
                      HorizontalAlignment="Center" VerticalAlignment="Center">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel IsItemsHost="True" Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <c:MusicalNotationBox/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
    

    (我认为,我没有包括它,如果&#34;单数&#34;一个是正确的,那么我的UserControl也是正确的。虽然可能是错的。)

3 个答案:

答案 0 :(得分:1)

您的用户控件的DataContextMusicalNotation对象,因此在绑定时而不是使用

Background="{Binding Path=MusicalNotation.IsSelected, Converter={StaticResource ....

只需使用

Background="{Binding Path=IsSelected, Converter={StaticResource ....

答案 1 :(得分:0)

由于您没有为所选项目或xaml中的IsSelected指定任何绑定,因此在VM中更改属性时,不会更新视图的原因。要更新视图,您必须为ItemsControl的SelectedItem属性提供绑定。

答案 2 :(得分:0)

从绑定中删除MusicalNotation前缀。

{Binding Path=IsSelected, ...