1

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

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

集合正确显示在数据网格中,我可以向数据网格添加新条目,但永远不会调用 OnCodeCollectionChanged 方法。我不想捕捉现有项目的更改(我知道 ObservableCollection 不会通知该更改),我只想在向集合中添加或删除新项目时引发更改事件。

我做错了什么,有没有更好的方法来做我想做的事?

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>

4

1 回答 1

1

填充集合后将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 的实例并且需要再次注册到该事件

于 2013-10-18T13:55:43.643 回答