Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当从另一个viewmodel调用函数时,RaisePropertyChanged未触发_C#_Wpf_Xaml_Windows Phone 7_Mvvm - Fatal编程技术网

C# 当从另一个viewmodel调用函数时,RaisePropertyChanged未触发

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绑定

我在更新正在使用的windows phone 7应用程序的界面时遇到问题

我有一个
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>
注意:我只是一个初级程序员,所以我处理问题的方式或程序本身可能有问题,因此我愿意接受任何建议,非常欢迎代码示例。在做了大量的研究和实验之后,我已经被这个问题困扰了好几天,而这些研究和实验似乎从来都不起作用。我花了时间详细地写了这个问题,我真的希望我能在这里找到解决办法。如果你需要知道更多细节,请告诉我。 提前谢谢

编辑:我读到创建视图的新实例不是一个解决方案。我还可以如何访问fire
MainView
的函数并引发属性

编辑:正如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()
    {
    ...
    }

}