C# 当从另一个viewmodel调用函数时,RaisePropertyChanged未触发
我在更新正在使用的windows phone 7应用程序的界面时遇到问题 我有一个C# 当从另一个viewmodel调用函数时,RaisePropertyChanged未触发,c#,wpf,xaml,windows-phone-7,mvvm,C#,Wpf,Xaml,Windows Phone 7,Mvvm,我在更新正在使用的windows phone 7应用程序的界面时遇到问题 我有一个MainPage.xaml及其MainViewModel.cs来处理子视图用户控件ChildView1.xaml在主页中的显示方式。ChildView1还有它的ViewModel,它是Child1ViewModel.cs。基本上,myToggleButton从主页触发,这将触发DataStateBehavior进入显示或隐藏状态,分别显示或隐藏ChildView1.xaml。该DataStateBehavior绑定
MainPage.xaml
及其MainViewModel.cs
来处理子视图用户控件ChildView1.xaml
在主页中的显示方式。ChildView1还有它的ViewModel,它是Child1ViewModel.cs
。基本上,myToggleButton
从主页触发,这将触发DataStateBehavior
进入显示或隐藏状态,分别显示或隐藏ChildView1.xaml
。该DataStateBehavior绑定到布尔值CanShowView
,而myToggleButton
绑定到名为Buttonched
的Icommand
,该命令具有中继功能SwitchVisibility
,可反转CanShowView
布尔值以显示或隐藏视图。由于我使用的MVVM指示灯的RaisePropertyChanged
,所有这些都可以正常工作
但是,ChildView1.xaml
有一个myCloseButton
,该按钮应该从MainViewModel调用SwitchVisibility
函数,该函数反过来会还原CanShowView
中的RaisePropertyChanged
,并且CanShowView
中的RaisePropertyChanged
应该触发以使ChildView1
关闭,但问题是,视图始终可见,并且由于某种原因永远不会关闭!我通过调试器注意到CanShowView
中的RaisePropertyChanged
似乎没有启动。我想这就是问题所在。我做错了什么?我怎样才能强迫它开火?我使用了多个RaisePropertyChanged
,但似乎没有一个触发,即使degugger显示我的函数中的值确实发生了变化
这是我的密码。
MainPage.xaml:
<phone:PhoneApplicationPage
...
>
<phone:PhoneApplicationPage.DataContext>
<Binding Path="Main" Source="{StaticResource Locator}"/>
</phone:PhoneApplicationPage.DataContext>
...
<Grid x:Name="LayoutRoot">
...
<ToggleButton x:Name="myToggleButton" Command="{Binding Main.ButtonChecked, Source={StaticResource Locator}}" >
<local:ChildView1 x:Name="myChildView1" Grid.Row="0" RenderTransformOrigin="0.5,0.5">
<i:Interaction.Behaviors>
<ec:DataStateBehavior Binding="{Binding Main.CanShowView, Source={StaticResource Locator}}" Value="True" TrueState="showChildView1" FalseState="hideChildView1"/>
</i:Interaction.Behaviors>
<local:ChildView1.RenderTransform>
<CompositeTransform/>
</local:ChildView1.RenderTransform>
</local:ChildView1>
</Grid>
</phone:PhoneApplicationPage>
ChildView1.xaml:
<UserControl x:Class="myApp.Views.ChildView1"
....
DataContext="{Binding Child1VM, Source={StaticResource Locator}}"
>
<Grid x:Name="HomeGrid">
<Button x:Name=myCloseButton Command="{Binding Child1VM.CloseChildViewCmd, Source={StaticResource Locator}}"/>
...
</Grid>
</UserControl>
注意:我只是一个初级程序员,所以我处理问题的方式或程序本身可能有问题,因此我愿意接受任何建议,非常欢迎代码示例。在做了大量的研究和实验之后,我已经被这个问题困扰了好几天,而这些研究和实验似乎从来都不起作用。我花了时间详细地写了这个问题,我真的希望我能在这里找到解决办法。如果你需要知道更多细节,请告诉我。
提前谢谢
编辑:我读到创建视图的新实例不是一个解决方案。我还可以如何访问fireMainView
的函数并引发属性
编辑:正如OmegaMan所建议的,我使用静态定义来调用我的函数。
因此,更新后的MainViewModel.cs
:
公共类MainViewModel:ViewModelBase
{
公共ICommand按钮{get;private set;}
私有静态MainViewModel主{get;set;}
public MainViewModel()
{
ButtonChecked = new RelayCommand(() => SwitchVisibility());
Primary = this;
}
public void SwitchVisibility()
{
CanShowView = !CanShowView;
RaisePropertyChanged("CanShowView");
}
public static void SwitchViewStatic()
{
Primary.SwitchVisibility();
}
bool _canShowView = true;
public bool CanShowView
{
get { return _canShowView; }
set
{
if (value != _canShowView)
{
_canShowView = value;
RaisePropertyChanged("CanShowView");
}
}
}
}
更新的Child1ViewModel.cs
:
名称空间myApp
{
公共类Child1ViewModel:ViewModelBase
{
public ICommand CloseChildViewCmd{get;private set;}
public Child1ViewModel()
{
CloseChildViewCmd=new RelayCommand(()=>ExecuteCloseChildViewCmd());
}
public void ExecuteCloseChildViewCmd()
{
MainViewModel.SwitchViewStatic();
}
}
}
myCloseButton会从子视图调用MainViewModel中所需的函数,但仍然无法调用
CanShowView
来允许DataStateBehavior监听该函数,以更新UI…因此我仍然处于僵局。问题是您正在向新的MainPage对象和视图模型发送消息,而不是向现有的MainPage对象和视图模型发送消息一个
你需要的是一个委托或一个事件。诀窍是将主页连接到子页
如果需要将它们分开,则需要一个对象来发送事件。这称为事件聚合器或messenger。主视图模型需要订阅子视图模型在执行命令时发送的CloseChild事件。事件聚合器传输消息
注意:大多数MVVM框架都实现了某种messenger,您的视图模型可以使用它来发送和接收消息/事件
如果您想自己实现一个,请寻找一种创建一个的方法。让子对象持有对主视图模型的引用没有什么错,但是为什么控件要创建一个新的MainViewModel?传入MainViewModel并调用SwitchVisibility关闭它…或者在MainVM上创建一个静态方法来访问实际VM和调用实例SwitchVisibility ---更新以显示来自MainVM的静态方法访问
public class MainViewModel : ViewModelBase
{
private static MainViewModel Primary { get; set; }
public MainViewModel()
{
Primary = this;
}
public static void SwitchViewStatic()
{
Primary.SwitchVisibility();
}
public void SwitchVisibility()
{
...
}
}
你在使用哪个mvvm框架?是的,看起来确实是错的。就像我对McGarnagle说的,我想我在某个地方读到它会调用应用程序的最新状态。在我以前的尝试中,我没有实例化视图,仍然无法引发属性。对于静态方法,你的意思是我可以创建例如
public static void LaunchSwitcher(){SwitchVisibility();}
并从子视图调用该方法?如果是这样,我如何从该子视图模型调用该方法而不实例化主视图,或者这无关紧要?感谢您的回复。@JNate对于静态方法的想法,让VM的构造函数自己填充到一个静态变量中(此实例的名称)。然后让静态方法使用该静态变量并调用SwitchVisibility。我研究了在何处创建静态变量以存储MainViewModel,但没有找到运气。您的意思是在MainViewModel中定义类似于public static var myVar=this
的内容吗?我试图定义它,但在var和this上收到错误消息这就是你所说的调用MainViewModel的静态变量吗?如果我能够创建myVar,我相信这就是它应该做的:public static void LaunchSwitcher(){myVar.SwitchVisibility();}
C
public void ExecuteCloseChildViewCmd()
{
MainViewModel.SwitchViewStatic();
}
}
}
public class MainViewModel : ViewModelBase
{
private static MainViewModel Primary { get; set; }
public MainViewModel()
{
Primary = this;
}
public static void SwitchViewStatic()
{
Primary.SwitchVisibility();
}
public void SwitchVisibility()
{
...
}
}