2

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

我有一个MainPage.xaml及其MainViewModel.cs处理子视图用户控件如何ChildView1.xaml出现在 MainPage 中的方法。ChildView1 也有它的 ViewModel,它是Child1ViewModel.cs. 基本上 amyToggleButton从 MainPage 触发,这将触发 aDataStateBehavior进入显示或隐藏状态以分别显示或隐藏ChildView1.xaml. DataStateBehavior 绑定到布尔值CanShowView,而myToggleButton绑定到具有中继功能的Icommand命名,该函数将反转布尔值以显示或隐藏视图。多亏了我使用的 MVVM 灯,一切都很好。ButtonCheckedSwitchVisibilityCanShowViewRaisePropertyChanged

然而,ChildView1.xaml有一个myCloseButton应该从 MainViewModel 调用该SwitchVisibility函数的函数,这反过来又会恢复CanShowViewRaisePropertyChangedinCanShowView应该触发以ChildView1关闭,但问题是视图保持可见并且由于某种原因永远不会关闭!我通过调试器注意到RaisePropertyChangedinCanShowView似乎没有触发。我想这就是问题所在。我做错了什么?我怎样才能强迫它开火?RaisePropertyChanged即使调试器显示我的函数中的值确实发生了变化,我也使用了多个但似乎没有触发。

这是我的代码。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();

        }
    }
}

注意:我只是一个初学者程序员,所以我解决问题的方式或程序本身可能是有问题的,因此我愿意接受任何建议,并且非常欢迎代码示例。在进行了大量研究并尝试了许多似乎从未奏效的事情之后,我已经被这个问题困扰了很多天。我花时间详细写了这个问题,我真的希望我能在这里找到解决方案。如果您需要了解更多详细信息,请告诉我。提前致谢。

编辑:我读到创建视图的新实例不是解决方案。我还能如何访问 fireMainView的功能并提高属性?

编辑:正如 OmegaMan 所建议的,我正在使用静态定义来调用我的函数。所以更新了MainViewModel.cs: public class MainViewModel : ViewModelBase { public ICommand ButtonChecked { get; 私人套装;} 私有静态 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 class Child1ViewModel : ViewModelBase { public ICommand CloseChildViewCmd { get; 私人套装;} public Child1ViewModel() { CloseChildViewCmd = new RelayCommand(() => ExecuteCloseChildViewCmd()); }

        public void ExecuteCloseChildViewCmd()
        {
            MainViewModel.SwitchViewStatic();

        }
    }
}

MainViewModel 中所需的函数由 myCloseButton 从子视图调用,但CanShowView仍然不会被提升以允许 DataStateBehavior 监听它,更新 UI ......所以我仍然处于僵局。

4

2 回答 2

1

问题是您正在向新的 MainPage 对象和视图模型发送消息,而不是现有的。

您需要的是委托或事件。诀窍是将主页连接到子页面。

如果您需要将它们分开,则需要一个对象来发送事件。这称为事件聚合器或信使。您的主视图模型需要订阅一个 CloseChild 事件,当命令执行时子视图模型将发送该事件。事件聚合器传输消息。

注意:大多数 MVVM 框架都实现了某种类型的信使,您的视图模型可以使用它来发送和接收消息/事件。

如果您想自己实现一个,请在此处查看创建方法。

于 2013-10-14T18:17:10.663 回答
1

让孩子持有对主视图模型的引用并没有错,但是为什么控件会创建一个新的 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()
    {
    ...
    }

}
于 2013-10-14T18:20:44.010 回答