5

次の例のコマンドが実行されないのはなぜですか?

AppBar と Button を含む名前付きの Page があります。

   <Page
    x:Class="App13.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" 
    x:Name="myPage"
    >
    <Page.BottomAppBar>
        <AppBar>
           <Button Content="OK" Command="{Binding OkCommand, ElementName=myPage}" />
        </AppBar>
    </Page.BottomAppBar>
</Page>

コマンド「OkCommand」は、コード ビハインドで次のように定義されます (MVVM ライト フレームワークを使用)。

public RelayCommand OkCommand
{
    get
    {
        return m_OkCommand
            ?? (m_OkCommand = new RelayCommand(
                                  async () =>
                                  {
                                      await new MessageDialog("OkCommand").ShowAsync();
                                  }));
    }
}

出力ウィンドウには、これが機能しない理由を示すバインディングエラーやその他のヒントはありません。(余談: ボタンが AppBar の外側に配置されている場合、すべて正常に動作します)

ここで何が間違っているのか誰にも分かりますか?

4

2 に答える 2

3

AppBarページの他の場所のボタンで機能する場合、コマンド バインディングがボタンで機能しない理由はありません。

問題は設定方法に関連していると思わDataContextれます。コントロール ツリーの下部ではなく、ページ レベルで設定する必要があります。他のすべてのボタンはページの上部のコンテンツ コントロールの内側にありますが、 がページの外側にあるため、 が上部のコンテンツ コントロールまたはそれより下に設定されてAppBarいる場合、バインディングが機能しません。DataContext

次の実際の例で試すことができます。

MainPage.xaml:

<common:LayoutAwarePage
    x:Class="App16.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App16"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:common="using:App16.Common"
    x:Name="MyPageName"
    mc:Ignorable="d">

    <StackPanel x:Name="MainGrid" Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Button Content="Ok" Command="{Binding OkCommand}" />
    </StackPanel>

    <Page.BottomAppBar>
        <AppBar x:Name="bottomAppBar" Padding="10,10,10,10"  >
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
                <Button Style="{StaticResource SkipBackAppBarButtonStyle}" Command="{Binding OkCommand}" >
                </Button>
            </StackPanel>
        </AppBar>
    </Page.BottomAppBar>
</common:LayoutAwarePage>

ViewModel.cs:

public class ViewModel
{
    private RelayCommand _okCommand;
    public RelayCommand OkCommand
    {
        get
        {
            return _okCommand
                ?? (_okCommand = new RelayCommand(
                                      async _ =>
                                      {
                                          await new MessageDialog("OkCommand").ShowAsync();
                                      }));
        }
    }
}

MainPage.xaml.cs:

public sealed partial class MainPage : LayoutAwarePage
{
    public MainPage()
    {
        this.InitializeComponent();
        DataContext = new ViewModel();
    }
}
于 2013-01-19T06:44:05.017 に答える
0

この質問が Windows RT/8 に関するものであることは承知していますが、ユニバーサル アプリ (UWP) で同じ問題に遭遇し、新しい {x:Bind} を使用して解決策を見つけました。デフォルトでは、x:Bind は、OneWay であった {Binding} ではなく OneTime にマップされることに注意してください。

新しい XAML Bind に関する MSDN Windows 10 Developer ビデオの 1 つを見ているときに、このパターンを見つけました。

YourPage.cs を変更する

public sealed partial class YourPage : Page
{
    public ViewModels.YourPageViewModel ViewModel { get; set; }

    public YourPage()
    {
        this.InitializeComponent();

        if (DesignMode.DesignModeEnabled) return;

        this.DataContextChanged += (s, e) =>
        {
            ViewModel = DataContext as ViewModels.YourPageViewModel;
        };
    }
}

YourPageViewModel.cs を変更する

public class YourPageViewModel : ViewModelBase
{
    private ICommand newFunctionCommand;
    public ICommand NewFunctionCommand { get { return newFunctionCommand; } }

    public YourPageViewModel()
    {
        if (DesignMode.DesignModeEnabled) return;

        if (newFunctionCommand == null)
            newFunctionCommand = new ICommand(new Action(NewFunction));
    }

    protected void NewFunction()
    {

    }
}

YourPage.xaml を変更する

<Page.DataContext>
    <vm:YourViewModel x:Name="YourVM" />
</Page.DataContext>

<Page.BottomAppBar>
    <CommandBar ClosedDisplayMode="Compact">
        <AppBarButton x:Name="AddAppBarButton" IsCompact="True"
                      Label="New" Icon="Add"
                      Command="{x:Bind ViewModel.NewFunctionCommand, Mode=OneWay}" />
    </CommandBar>
</Page.BottomAppBar>
于 2015-10-09T18:57:31.697 に答える