繁体   English   中英

WPF:OnCollectionChanged不触发

[英]WPF: OnCollectionChanged not firing

使用VS 2102,.NET 4.0和MVVM Light。

我有以下代码将项目从XML文件读取到ObservableCollection中。 然后,如果集合发生更改(使用IsDirty标志),但未执行OnCodeCollectionChanged方法,则我想用Converter更新Save按钮。

该集合正确显示在数据网格中,我可以向数据网格中添加新条目,但是从不调用OnCodeCollectionChanged方法。 我不是要捕获现有项目的更改(我知道ObservableCollection不会通知该更改),如果要将新项目添加到集合中或从集合中移除,我只想引发on change事件。

我在做什么错,有没有更好的方式来做我想做的事情?

Codes.cs(模型)

[Serializable()]
public class Codes
{
    public Codes() { }

    [XmlElement("Code")]
    public ObservableCollection<Code> CodeCollection { get; set; }

}

[Serializable()]
public class Code
{
    [XmlElement("AccpacCode")]
    public string AccpacCode { get; set; }

    [XmlElement("LAC")]
    public string LAC { get; set; }

    [XmlElement("SCSCode")]
    public string SCSCode { get; set; }

    [XmlElement("ParentEmployerAccpacCode")]
    public string ParentEmployerAccpacCode { get; set; }
}

MainViewMdoel.cs(ViewModel)

public class MainViewModel : ViewModelBase
{
    public bool IsDirty = false;

    /// <summary>
    /// ObservableCollection of Codes
    /// </summary>
    private const string CodeCollectionPropertyName = "CodeCollection";
    private ObservableCollection<Code> _codeCollection;
    public ObservableCollection<Code> CodeCollection
    {
        get
        {
            if (_codeCollection == null)
            {
                _codeCollection = new ObservableCollection<Code>();
            }
            return _codeCollection;
        }
        set
        {
            if (_codeCollection == value)
            {
                return;
            }

            _codeCollection = value;
            RaisePropertyChanged(CodeCollectionPropertyName);
        }
    }

    /// <summary>
    /// Initializes a new instance of the MainViewModel class.
    /// </summary>
    public MainViewModel(IDataService dataService)
    {
        // Change notification setup
        CodeCollection.CollectionChanged += OnCodeCollectionChanged;

        // Load XML file into ObservableCollection
        LoadXML();
    }

    private void LoadXML()
    {
        try
        {
            XmlSerializer _serializer = new XmlSerializer(typeof(Codes));

            // A file stream is used to read the XML file into the ObservableCollection
            using (StreamReader _reader = new StreamReader(@"LocalCodes.xml"))
            {
                CodeCollection = (_serializer.Deserialize(_reader) as Codes).CodeCollection;

            }                
        }
        catch (Exception ex)
        {
            // Catch exceptions here
        }

    }

    private void SaveToXML()
    {
        try
        {

        }
        catch (Exception ex)
        {

        }
    }

    private RelayCommand<ViewModelBase> _saveButtonClickedCommand;
    public RelayCommand<ViewModelBase> SaveButtonClickedCommand;
    private void SaveButtonClicked(ViewModelBase viewModel)
    {
        SaveToXML();
    }

    private void OnCodeCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        IsDirty = true;
    }
}

MainWindow.xaml(查看)

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Skins/MainSkin.xaml" />
        </ResourceDictionary.MergedDictionaries>

        <conv:IsDirtyConverter x:Key="IsDirtyConverter" />

    </ResourceDictionary>
</Window.Resources>

<Grid x:Name="LayoutRoot">

    <TextBlock FontSize="36"
               FontWeight="Bold"
               Foreground="Purple"
               Text="{Binding WelcomeTitle}"
               VerticalAlignment="Top"
               TextWrapping="Wrap" Margin="10,10,10,0" Height="54" HorizontalAlignment="Center" />

    <DataGrid Margin="10,69,10,38"
              ItemsSource="{Binding CodeCollection}"/>
    <Button Name="SaveButton" Content="Save" HorizontalAlignment="Right" Margin="0,0,90,10" Width="75"
            Command="{Binding SaveButton_Click}"
            Background="{Binding IsDirty, Converter={StaticResource IsDirtyConverter}}" Height="20" VerticalAlignment="Bottom"/>
    <Button Content="Refresh" HorizontalAlignment="Right" Margin="0,0,10,10" Width="75"
            Command="{Binding RefreshButton_Click}" Height="20" VerticalAlignment="Bottom"/>

</Grid>

移动您的CodeCollection.CollectionChanged += OnCodeCollectionChanged; 填充集合后,将代码从构造函数转换为LoadXml代码

    private void LoadXML()
    {
        try
        {
            XmlSerializer _serializer = new XmlSerializer(typeof(Codes));

            // A file stream is used to read the XML file into the ObservableCollection
            using (StreamReader _reader = new StreamReader(@"LocalCodes.xml"))
            {
                CodeCollection.CollectionChanged -= OnCodeCollectionChanged;
                CodeCollection = (_serializer.Deserialize(_reader) as Codes).CodeCollection;
                CodeCollection.CollectionChanged += OnCodeCollectionChanged;

            }                
        }

您正在更改CodeCollection的实例,需要再次注册该事件

暂无
暂无

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

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