3

この分野には多くの疑問があるはずですが、私の場合、役立つものは何も見つかりませんでした。

私が経験している問題は、ViewModel、特に ViewModel 内のプロパティを View に更新することです。以下は私の実装です。どこが間違っているのかは理解していると思いますが、それを解決する方法がわかりません。

リストと編集ビューを持つモジュールがあります。ドメイン オブジェクトと、ドメイン オブジェクトを編集する機能を非常に単純に一覧表示します。

私の xaml は、DataContent を View の ViewModel プロパティにバインドします。

次に、INavigationAware.NavigateTo メソッドを使用して ViewModel に移動し、ここでドメイン オブジェクトを読み込みます。

問題は、明らかにこれがビューに反映されないことです。ビューには既に ViewModel のインスタンスがあります。このメソッドは、ViewModel が ObservableCollection を使用してオブジェクトのリストを使用しているときに正常に機能しました。ただし、これは、単純なオブジェクトまたは ObservableObject を使用している場合には機能しませんでした。

誰かが私の理解を助けてくれますか、私が達成しようとしていることをより適切に実装するためのリンクをいくつか教えてもらえますか?

マイモジュール

public class MyModule : IModule
{
    private readonly IRegionManager _regionManager;

    public MyModule(IRegionManager regionManager)
    {
        _regionManager = regionManager;
    }

    public void Initialize()
    {
        _regionManager.RegisterViewWithRegion(Constants.MainRegionName, typeof(MyListView));
        _regionManager.RegisterViewWithRegion(Constants.MainRegionName, typeof(MyEditView));
    }
}

XAML

<UserControl
    DataContext="ViewModel">
    ...
    <TextBlock Text="{Binding Path=MyDomainObject.AProperty}" />
    ...

意見

public partial class MyEditView
{
    public readonly static string ViewName = "MyEditView";

    public MyEditView(MyEditViewModel viewModel)
    {
        InitializeComponent();
        ViewModel = viewModel;
    }

    public MyEditViewModel ViewModel
    {
        get { return DataContext as MyEditViewModel; }
        private set { DataContext = value; }
    }
}

ビューモデル

public class MyViewModel : INavigationAware
{
    private readonly IRegionManager _regionManager;

    public MyDomainObject MyDomainObject { get; set; }

    public void Load(ViewModelKey key)
    {
        // get domain object
        // this method worked when MyDomainObject was 
        // ObservableCollection<T> as just adding elements to list
        // where this is creating a new instance of MyDomainObject
        var id = parameter from navigationContext;
        MyDomainObejct = server.GetDomainObject(id);
    }

    public void OnNavigatedTo(NavigationContext navigationContext)
    {
        var key = key from navigationContext;
        Load(key);
    }
}

解決

public class MyEditViewModel : INavigationAware
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged([CallerMemberName]string propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private MyDomainObject _myDomainObject;
    public MyDomainObject MyDomainObject
    {
        get
        {
            return _myDomainObject;
        }
        set
        {
            if (value != _myDomainObject)
            {
                _myDomainObject = value;
                NotifyPropertyChanged();
            }
        }
    }

意見

public partial class MyEditView
{
    public MyEditView(MyEditViewModel viewModel)
    {
        InitializeComponent();
        ViewModel = viewModel;

        ViewModel.PropertyChanged += ViewModel_PropertyChanged;
    }

    public MyEditViewModel ViewModel
    {
        get { return DataContext as MyEditViewModel; }
        private set { DataContext = value; }
    }

    private void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (!(sender is MyEditViewModel))
            return;

        ViewModel = (MyEditViewModel)sender;
    }
}
4

1 に答える 1