2

作業中の Windows Phone 7 アプリのインターフェイスを更新する際に問題が発生しています。

MainPage で子ビューのユーザー コントロールがどのように表示されるかを処理しMainPage.xamlます。ChildView1 には、その ViewModel もあります。基本的に、は MainPage から起動されます。これにより、 が表示または非表示の状態になり、それぞれ が表示または非表示になります。その DataStateBehavior はブール値にバインドされ、 はブール値を逆にしてビューを表示または非表示にするリレー関数を持つ名前付きにバインドされます。私が使用したMVVMライトのおかげで、すべてうまくいきました。MainViewModel.csChildView1.xamlChild1ViewModel.csmyToggleButtonDataStateBehaviorChildView1.xamlCanShowViewmyToggleButtonIcommandButtonCheckedSwitchVisibilityCanShowViewRaisePropertyChanged

ただし、MainViewModel から関数を呼び出すことになってChildView1.xamlいる があり、これにより が元に戻り、inが起動して閉じる必要がありますが、問題は、ビューが表示されたままになり、何らかの理由で閉じないことです! デバッガーを介して、 in が起動しないように見えることに気付きました。そこが問題だと思います。私の何が間違っていますか?どうすれば強制的に発火させることができますか? 複数を使用しましたが、機能の値が変更されたことをデガガーが示していても、何も起動していないようです。myCloseButtonSwitchVisibilityCanShowViewRaisePropertyChangedCanShowViewChildView1RaisePropertyChangedCanShowViewRaisePropertyChanged

これが私のコードです。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();

        }
    }
}

注: 私は初心者のプログラマーにすぎないため、問題への取り組み方やプログラム自体に疑問がある可能性があります。したがって、あらゆる提案を歓迎します。コード サンプルは大歓迎です。多くの調査を行い、うまくいかなかった多くのことを実験した後、私は何日もこの問題に悩まされてきました. 私は時間をかけて問題を詳細に書きましたが、ここで解決策を見つけることができることを本当に願っています. あなたが知る必要がある詳細があれば教えてください。前もって感謝します。

編集:ビューの新しいインスタンスを作成することは解決策ではありません。MainViewの関数を起動し、プロパティを発生させるには、他にどのようにアクセスできますか?

編集: OmegaMan で提案されているように、静的定義を使用して関数を呼び出しています。したがって、更新されたMainViewModel.cs: public class MainViewModel : ViewModelBase { public ICommand ButtonChecked { get; プライベートセット; } プライベート静的 MainViewModel プライマリ { get; 設定; }

    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: namespace myApp { public class Child1ViewModel : ViewModelBase { public ICommand CloseChildViewCmd { get; プライベートセット; } public Child1ViewModel() { CloseChildViewCmd = new RelayCommand(() => ExecuteCloseChildViewCmd()); }

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

        }
    }
}

MainViewModel の目的の関数は、子ビューから myCloseButton によって呼び出されますが、CanShowViewDataStateBehavior がそれをリッスンして UI を更新できるようにするために発生することはありません...だから、私はまだ行き詰まっています。

4

2 に答える 2

1

問題は、既存のものではなく、新しい MainPage オブジェクトとビュー モデルにメッセージを送信していることです。

必要なのは、デリゲートまたはイベントのいずれかです。コツは、メイン ページを子ページに接続することです。

それらを別々に保持する必要がある場合は、イベントを送信するためのオブジェクトが必要です。これは Event Aggregator またはメッセンジャーと呼ばれます。メイン ビューモデルは、コマンドの実行時に子ビュー モデルが送信する CloseChild イベントをサブスクライブする必要があります。イベント アグリゲーターがメッセージを転送します。

注: ほとんどの MVVM フレームワークは、ビュー モデルがメッセージやイベントの送受信に使用できる何らかのメッセンジャーを実装しています。

自分で実装したい場合は、ここで作成方法を確認してください。

于 2013-10-14T18:17:10.663 に答える