我在更新正在处理的Windows Phone 7应用程序的界面时遇到问题。

我有一个MainPage.xaml及其MainViewModel.cs,用于处理 subview 用户控件ChildView1.xaml在MainPage中的显示方式。 ChildView1也有其ViewModel,它是Child1ViewModel.cs。基本上,会从MainPage中触发myToggleButton,这将触发DataStateBehavior进入显示或隐藏状态以分别显示或隐藏ChildView1.xaml。该DataStateBehavior绑定(bind)到 bool CanShowView,而myToggleButton绑定(bind)到名为IcommandButtonChecked,它具有中继功能SwitchVisibility,该函数将反转CanShowView bool 以显示或隐藏 View 。多亏我使用的MVVM灯的RaisePropertyChanged,所有工作都很好。

但是,ChildView1.xaml有一个myCloseButton,应该从MainViewModel调用SwitchVisibility函数,这又会还原CanShowView,并且RaisePropertyChanged中的CanShowView应该触发以关闭ChildView1,但是问题是 View 保持可见并且对于某些 View 永远不会关闭原因!我通过调试器注意到RaisePropertyChanged中的CanShowView似乎没有触发。我想这就是问题所在。我做错了什么?我该如何迫使它开火?我使用了多个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>

MainViewModel.cs:
public class MainViewModel : ViewModelBase
{
    public ICommand ButtonChecked { get; private set; }

    public MainViewModel()
    {
        ButtonChecked = new RelayCommand(() => SwitchVisibility());
    }

    public void SwitchVisibility()
    {
        CanShowView = !CanShowView;
        RaisePropertyChanged("CanShowView");
    }

    bool _canShowView = true;
    public bool CanShowView
    {
        get { return _canShowView; }
        set
        {
            if (value != _canShowView)
            {
                _canShowView = value;
                RaisePropertyChanged("CanShowView");
            }
        }
    }

}

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>

Child1ViewModel.cs:
namespace myApp
{
    public class Child1ViewModel : ViewModelBase
    {
        public ICommand CloseChildViewCmd { get; private set; }
        public Child1ViewModel()
        {
            CloseChildViewCmd = new RelayCommand(() => ExecuteCloseChildViewCmd());
        }

        public void ExecuteCloseChildViewCmd()
        {
            MainPage mainPage = new MainPage();
            MainViewModel mainVM = new MainViewModel();
            mainPage.DataContext = mainVM;
            mainVM.SwitchVisibility();

        }
    }
}

注意:我只是一个初学者,所以我解决问题或程序本身的方式可能会令人怀疑,因此我愿意接受任何建议,非常欢迎代码示例。经过大量研究和尝试了许多似乎行不通的事情之后,我已经被困扰了很多天。我花了一些时间详细地写了这个问题,非常希望能在这里找到解决方案。让我知道您是否需要了解更多详细信息。
提前致谢。

编辑:我读过创建 View 的新实例不是解决方案。我还能如何访问MainView的函数并引发属性?

编辑:正如由OmegaMan建议,我正在使用静态定义来调用我的函数。
因此,更新后的MainViewModel.cs:
公共(public)类MainViewModel:ViewModelBase
{
公共(public)ICommand ButtonChecked {私有(private)套装; }
私有(private)静态MainViewModel主要{放; }
    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
{
公共(public)类Child1ViewModel:ViewModelBase
{
公共(public)ICommand CloseChildViewCmd {get;私有(private)套装; }
公共(public)Child1ViewModel()
{
CloseChildViewCmd = new RelayCommand(()=> ExecuteCloseChildViewCmd());
}
        public void ExecuteCloseChildViewCmd()
        {
            MainViewModel.SwitchViewStatic();

        }
    }
}

MainViewModel中所需的函数由 subview 中的myCloseButton调用,但是CanShowView仍然不会提高以允许DataStateBehavior监听它,以更新UI ...因此,我仍然处于僵局。

最佳答案

让 child 拥有对主 View 模型的引用没有错,但是为什么控件要创建一个新的MainViewModel?传入MainViewModel并调用SwitchVisibility ...或者在MainVM上创建一个静态方法,该方法将访问实际的VM并调用实例SwitchVisiblity。

---更新以显示来自MainVM的静态方法访问

public class MainViewModel : ViewModelBase
{
    private static MainViewModel Primary { get; set; }

    public MainViewModel()
    {
        Primary = this;
    }

    public static void SwitchViewStatic()
    {
        Primary.SwitchVisibility();
    }

    public void SwitchVisibility()
    {
    ...
    }

}

关于c# - 从另一个 View 模型调用函数时,不会触发RaisePropertyChanged,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19366174/

10-10 19:30