2
private ObservableCollection<ProjectItem> _projectItems;

public ObservableCollection<ProjectItem> DataItems
    {
        get { return _projectItems; }
    }

public ProjectsPanelViewViewModel()
    {
        _projectItems = new ObservableCollection<ProjectItem>();
        _createProjectCommand = new DelegateCommand(OnCreateProjectCommand);
        _saveProjectCommand = new DelegateCommand(OnSaveProjectCommand);
    }

private void OnCreateProjectCommand()
    {
        _addProjectViewModel = new AddProjectViewModel();
        AddProjectView view = new AddProjectView();
        view.Show();
    }

    private void OnSaveProjectCommand()
    {
        ProjectItemViewModel _vm = new ProjectItemViewModel();
        _vm.ProjectName = ProjectName;
        _vm.ProjectDescription = ProjectDescription;
        var item = new ProjectItem(_vm);
        _projectItems.Add(item);
    }

XAML

<UserControl.DataContext>
    <VM:ProjectsPanelViewViewModel/>
</UserControl.DataContext>
<StackPanel Name="ProjectsPanel" Style="{DynamicResource FullLengthPanelStyle}" >
    <StackPanel Name="ProjectsHeader" Orientation="Horizontal" Margin="0,0,0,5">
        <Label Style="{StaticResource TitleLabelStyleBlue}">projects</Label>
        <Button Name="AddProjects" Margin="10,5,0,0" Style="{StaticResource CircularGreyButtonStyle}" Content="+" ToolTip="Add a new project" Command="{Binding CreateProjectCommand}"/>
        <Button Name="ExpandProjects" Margin="10,5,0,0" Style="{StaticResource CircularGreyButtonStyle}" Content=">" ToolTip="Expand projects"/>
    </StackPanel>

    <ScrollViewer VerticalScrollBarVisibility="Visible">
            <ItemsControl ItemsSource="{Binding DataItems}"/>
    </ScrollViewer>
</StackPanel>

OnCreateProjectCommand が開くと、2 つの文字列フィールドを持つウィンドウが作成され、OnSaveProjectCommand を実行するボタンが表示されます。コマンドは正常に実行されますが、UI は新しいアイテムがコレクションに追加されたことを認識しません。(デバッグするときはそこにあります)。ただし、コードを OnSaveProjectCommand から変更して OnCreateProjectCommand に配置し、単純な文字列値をハードコードすると、UI は監視可能なコレクションから正しく更新されます。

これが機能しない理由と、このコマンドから新しいウィンドウを生成する正しい方法について、誰かが私にガイダンスを与えることができますか? これは、プリズムからの状態ベースのビュー ナビゲーションで行う必要がありますか? 私たちはすでにこれをモジュール化と指揮のために使用しています。

アドバイスをありがとう。

4

2 に答える 2

2

そこに参照の問題がある可能性があると思います。この ViewModel を互いにどのように接着しますか? 私は Prism に詳しくありませんが、画面に表示されている VM インスタンスが、デバッグしている VM インスタンスと異なる場合があります。そうでなければ意味がありません。Observablecollections は、UI スレッド以外の別のスレッドから操作しない限り、通常は問題なく動作します。Snoopを使用して実行中のアプリケーションをスパイし、DataContext が何であるかを確認してみてください。

于 2012-10-30T18:46:51.503 に答える
2

HighCores のアドバイスに加えてCollectionChanged、ObservableCollection から Event にイベント ハンドラーをアタッチします。イベントが発生した場合、少なくとも ObservableCollection の NotifyPropertyChanged を手動で発生させることができます。

編集

例:

using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;

namespace CollectionChangedSpike
{
    public class ViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<ProjectItem> _projectItems = new ObservableCollection<ProjectItem>();
        public ObservableCollection<ProjectItem> ProjectItems
        {
            get { return _projectItems; }
            set { _projectItems = value; OnPropertyChanged("ProjectItems");}
        }

        public ViewModel()
        {
            //Just for debugging
            ProjectItems.CollectionChanged += OnProjectItemsChanged;
        }

        private void OnProjectItemsChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            OnPropertyChanged("ProjectItems");
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }


    }
}
于 2012-10-31T07:29:11.783 に答える