【问题标题】:How to navigate in WPF using PRISM and bind DataContext如何使用 PRISM 在 WPF 中导航并绑定 DataContext
【发布时间】:2012-11-19 10:26:10
【问题描述】:

这个领域肯定有很多问题,但我找不到任何可以帮助我的例子。

我遇到的问题是让我的 ViewModel,特别是 ViewModel 中的一个属性,更新到我的 View。下面是我的实现。我想我知道哪里出了问题,但不知道如何解决。

我有一个具有列表和编辑视图的模块。非常简单地列出域对象,然后能够编辑域对象。

我的 xaml 将 DataContent 绑定到我的视图中的 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;
    }
}

【问题讨论】:

    标签: c# wpf mvvm prism


    【解决方案1】:

    要更新绑定,您需要实现INotifyPropertyChanged 并在域对象的 set 访问器上引发 PropertyChanged 事件。

    public event PropertyChangedEventHandler PropertyChanged = delegate {};
    
    
    public MyDomainObject MyDomainObject
    {
        get
        {
            return myDomainObject;
        }
        set
        {
            if(value != myDomainObject)
            {
                myDomainObject = value;
                RaisePropertyChanged("MyDomainObject");
            }
        }
    }
    
    private void RaisePropertyChanged(String p)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(p));
    }
    

    或者在 Prism 书中,继承 NotificationObject 并调用 RaisePropertyChanged(()=> PropertyName) ,这是重构安全的

    【讨论】:

      猜你喜欢
      • 2011-03-12
      • 2015-03-19
      • 2011-09-12
      • 2012-10-31
      • 1970-01-01
      • 1970-01-01
      • 2010-11-26
      • 2018-04-08
      • 1970-01-01
      相关资源
      最近更新 更多