刷新使用UpdateLayout或其他替代方法查看数据绑定 [英] Refresh View databindings using UpdateLayout or some other alternative

查看:630
本文介绍了刷新使用UpdateLayout或其他替代方法查看数据绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  RedScreenViewModel:IScreenViewModel 
GreenScreenViewModel:IScreenViewModel

etc ..
这意味着我有一个RedScreenView.xaml,它制作一个RedScreenViewModel实例,对于所有后续的彩色屏幕也是如此。

  IScreenViewModel有一些必须实现的属性,例如
接口IScreenViewModel
{
public Color ScreenColor {get; set;}
}

我有一个ViewmodelWrapper类,它保存所有viewmodels实例。 ScreenViewModels,MenuViewModels等...
因为我使用的是DevExpress,我不能直接在Main.xaml.cs文件中绑定DataContext,原因我还不知道。
所以在主要例如。
我不能有

  ScreenLabel.DataContext = viewModelWrapper.ScreenViewModel 

我要做的主要是:

  DataContext = viewModelWrapper; 

这样,父窗口可以看到所有的子元素。



在RedScreenView.xaml中,我可以这样做:

 < Label Background =ScreenViewModel.ScreenColor /> 

希望数据绑定应该在ViewModelWrapper中查找IScreenViewModel.ScreenViewModel对象,并使用正确的ScreenColor对象使用动态绑定/多态。



有些情况下,一个屏幕可以有更多的属性,所以说在
GreenScreenViewModel以及ScreenColor属性继承,它可以有自己的属性可能 DifferentProperty



问题是:我有一个Factory返回一个屏幕对象,具体取决于用户想要什么屏幕它返回正确的屏幕对象,但是当它通知视图进行更新时,会看到新对象,但是使用错误的XAML 。如果那有意义的话。
我在ViewModelWrapper方法中做这样的事情。

  MainGui.ScreenWrapper.LayoutRoot.Clear(); 
MainGui.ScreenWrapper.Items.Clear();
MainGui.ScreenWrapper.LayoutRoot.Add(screenFactory.GetSelectedScreen(RedScreen)。GetLayoutRoot()
MainGui.UpdateLayout();
ScreenViewModel = screenFactory.GetSelectedScreen(RedScreen)。GetViewModel ();

忽略我调用工厂两次的事实...
ScreenWrapper是LayoutGroup当我使用该代码交换视图(屏幕)时,我希望它使用正确的绑定。
那么说我从GreenScreenViewModel交换到RedScreenViewModel,记住GreenScreenViewModel比RedScreenViewModel还要一个属性GreenScreenView我有这样的东西:

 < Label Content =ScreenViewModel.DifferentProperty/> 

当交换完成后,ScreenViewModel通知现在指向RedScreenViewModel会抛出异常,我强烈地假设这是因为布局不被刷新,它仍然使用t他错误的看法
调试模式下的输出错误是
ViewModelWrapper.ScreenModel中找不到属性DifferentProperty
哪个不正确,因为我已经删除了GreenScreenView,我更新了布局,我知道那里是一个LayoutChanged事件或类似的事情,所以这可能已经被提出,为什么它仍然看到错误的视图?
如何更新ScreenWrapper.LayoutRoot以使用不同的绑定代码查看新的View。
天啊,我希望很清楚。
编辑:迈克尔感谢答复。是的,有一个实际的异常 - 我在使用的第三方DLL中的NullReferenceException。那是因为它找不到属性。我相信我没有说清楚,但也许问题应该是:当从视觉树中删除和插入用户控件时,我可以刷新可视化树来看到新的绑定吗?如果我可以刷新视觉树,它应该解决我的问题。 UpdateLayout()不起作用



编辑:
在Michael感谢您的回复。是的,有一个实际的异常 - 我在使用的第三方DLL中的NullReferenceException。那是因为它找不到属性。当我调用OnPropertyChanged时抛出异常,并且处理程序不为null!
我确信我没有说清楚,但也许问题应该是:
从视觉树中删除和插入usercontrol时,我可以刷新可视化树来看新的绑定吗?如果我可以刷新视觉树,它应该解决我的问题。
UpdateLayout()不起作用。

解决方案

首先,你说



Express不应该是这里的问题。您需要绑定的东西才能返回相应的ViewModel。看看这里,讨论这个问题。



其次,你说错误是


在viewModelWrapper.ScreenModel中找不到属性DifferentProperty


这不一定是问题,并不会造成例外。当您动态更改绑定时,INotifyPropertyChanged事件会在整个地方飞行,并且可能会有一段不确定性。我假设你的ViewModels实现INotifyPropertyChanged。



我认为关键可能是更接近异常,如果有一个(因为找不到属性是一个调试消息,不是例外)。要清楚一点,您可能需要关闭绑定消息,如 here 。如果有一个实际例外,请修改细节。


I have an interface IScreenViewModel, and to simplify the problem I can

RedScreenViewModel : IScreenViewModel
GreenScreenViewModel : IScreenViewModel

etc.. This means I have a RedScreenView.xaml which makes a RedScreenViewModel instance, likewise for all subsequent color screens.

IScreenViewModel has some properties that you must implement e.g. 
interface IScreenViewModel
{
   public Color ScreenColor{get;set;}
}

I have a ViewmodelWrapper class which holds all viewmodels instances. ScreenViewModels, MenuViewModels etc... Because I am using DevExpress I can't bind the DataContext directly in the Main.xaml.cs file for reasons I still don't know yet. So in main for example. I can't have

ScreenLabel.DataContext  = viewModelWrapper.ScreenViewModel

I would have to do in main:

DataContext  = viewModelWrapper;

This way the parent Window can see all child elements.

In a RedScreenView.xaml I can have something like this:

<Label Background="ScreenViewModel.ScreenColor"/>

And hopefully the data binding should look in the ViewModelWrapper find the IScreenViewModel.ScreenViewModel object and use the correct ScreenColor object using dynamic binding/polymorphism.

There are cases where a screen can have more properties, so let say in GreenScreenViewModel along with ScreenColor property inherited, it can have its own property maybe DifferentProperty.

The problem is: I have a Factory that returns a screen object depending on what screen the user wants. It returns the correct screen object, but when it notifies the View to update itself it looks at the new object but using the wrong XAML. If that makes any sense. I do something like this in a ViewModelWrapper method.

MainGui.ScreenWrapper.LayoutRoot.Clear() ;
MainGui.ScreenWrapper.Items.Clear() ;
MainGui.ScreenWrapper.LayoutRoot.Add(screenFactory.GetSelectedScreen("RedScreen").GetLayoutRoot()
    MainGui.UpdateLayout() ;
    ScreenViewModel = screenFactory.GetSelectedScreen("RedScreen").GetViewModel() ;

Ignore the fact that I called factory twice... ScreenWrapper is LayoutGroup that holds the screens. When I swap the Views (screens) using that code I am hoping that it would use the correct bindings. So let's say I swap from GreenScreenViewModel to RedScreenViewModel, remember GreenScreenViewModel one more property than RedScreenViewModel and in the GreenScreenView I had something like this:

<Label Content="ScreenViewModel.DifferentProperty"/> 

When the swap is done and ScreenViewModel notifies that is now pointing to RedScreenViewModel it throws an exception. I am strongly assuming this is because Layout isn't being refreshed and it is still using the wrong view. The output error in debug mode is "Cannot find property DifferentProperty in viewModelWrapper.ScreenModel" Which isn't right because I have already deleted THAT GreenScreenView, I updated the layout, I know there is a LayoutChanged event or something like that, so that could have been raised as well so why is it still seeing the wrong View? How can I update ScreenWrapper.LayoutRoot to "see" the new View with a different binding code. Heavens, I hope that was clear. EDIT: At Michael thanks for replying. Yes there is an actual exception - "NullReferenceException" in the thirdparty dll I am using. And that is because it can't find the property. I am sure I didn't make myself clear but maybe the question should be: When deleting and inserting usercontrols from a visual tree -how can I refresh the visual tree to see new bindings? If I can refresh the visual tree it should solve my problem. UpdateLayout() doesn't work

EDIT: At Michael thanks for replying. Yes there is an actual exception - "NullReferenceException" in the thirdparty dll I am using. And that is because it can't find the property. It throws the exception when I call OnPropertyChanged, and yeah the handler isn't null! I am sure I didn't make myself clear but maybe the question should be: When deleting and inserting usercontrols from a visual tree -how can I refresh the visual tree to see new bindings? If I can refresh the visual tree it should solve my problem. UpdateLayout() doesn't work.

解决方案

Firstly, you say

Because I am using DevExpress I can't bind the DataContext directly in the Main.xaml.cs file for reasons I still don't know yet.

Express should not be the problem here. You need something to bind to that will return the appropriate ViewModel. Have a look here for discussion on this subject.

Secondly, you say the error is

Cannot find property DifferentProperty in viewModelWrapper.ScreenModel

This is not necessarily a problem, and does not cause an exception. When you change bindings dynamically, INotifyPropertyChanged events fly off all over the place and there may be a period of 'uncertainty'. I am assuming your ViewModels implement INotifyPropertyChanged.

I think the key is probably looking closer at the exception, if there is one (because "Cannot find property" is a debug message, not an exception). To get some clarity you might want to turn off the binding message as described here. If there is an actual exception, please edit with the details.

这篇关于刷新使用UpdateLayout或其他替代方法查看数据绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆