【问题标题】:Using Command attribute in Windows 8.1 Store App TopAppBar在 Windows 8.1 Store App TopAppBar 中使用 Command 属性
【发布时间】:2014-06-01 01:04:20
【问题描述】:

我正在尝试在 Windows 应用商店应用程序中有效使用 TopAppBar。我使用了基本页面模板,并以与实现 GoForwardCommand 和 GoBackCommand 相同的方式将 NavigateCommand 添加到 NavigationHelper 类。我还在 RelayCommand 中添加了一个构造函数,以使 Execute 和 CanExecute 委托能够获取对象参数

    public RelayCommand(Action<object> execute, Func<object, bool> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");
        _executeWithParam = execute;
        _canExecuteWithParam = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? (_canExecuteWithParam == null ? true : _canExecuteWithParam(parameter)) : _canExecute();
    }

    public void Execute(object parameter)
    {
        if (_execute == null)
            _executeWithParam(parameter);
        else
            _execute();
    }

在我的 MainPage XAML 中,我有以下代码:

<Page
x:Name="pageRoot"
x:Class="UniAppTest.MainPage"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UniAppTest"
xmlns:common="using:UniAppTest.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<Page.Resources>
    <!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
    <x:String x:Key="AppName">Welcome to universal apps!</x:String>
</Page.Resources>

<Page.TopAppBar>
    <AppBar>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <StackPanel Orientation="Horizontal">
                <Button Content="Home" Width="140" Height="80" />
                <Button Content="Summary" Width="140" Height="80" 
                        Command="{Binding NavigateCommand}"
                        CommandParameter="SummaryPage" />
                <Button Content="Reports" Width="140" Height="80" 
                        Command="{Binding NavigationHelper.NavigateCommand, ElementName=pageRoot}"
                        CommandParameter="ReportsPage " />
            </StackPanel>
            <SearchBox Grid.Column="1" Width="300" Height="50" HorizontalAlignment="Right" />
        </Grid>
    </AppBar>
</Page.TopAppBar>

两个按钮都不会在按下时调用命令。

但是,如果我在主页内容中添加一个按钮,则该命令会成功运行:

        <Button x:Name="summaryButton" Margin="39,59,39,0" 
        Command="{Binding NavigationHelper.NavigateCommand, ElementName=pageRoot}"
        CommandParameter="SummaryPage"
        Grid.Row="1" Content="Summary"
        Style="{StaticResource TextBlockButtonStyle}"
        VerticalAlignment="Top"
        FontSize="24"/>

谁能帮我看看我做错了什么。我认为它必须在 Binding 参考中。我总是觉得这很令人困惑。将不胜感激任何帮助。谢谢。

【问题讨论】:

  • 也许应用栏有一个单独的名称范围。您可以检查 Visual Studio 输出窗口中的绑定错误消息吗?

标签: windows binding command windows-store-apps winrt-xaml


【解决方案1】:

嗯...据我所知,您没有将任何内容绑定到 top.appbar 或父级,因此当它尝试查看时,必须去寻找他不知道的命令。 当您在一个简单的按钮中制作它时,该按钮有一个带有 Bind 的父级,不是吗?

【讨论】:

  • 好吧,我正在绑定到页面的属性,并且在命令绑定中我指定 ElementName=pageRoot,据我所知,我不需要将任何内容绑定到页面。页面主体上的按钮肯定可以正常工作。我想这与附加属性的 AppBars 有关。我已经尝试绑定到 AppBar 本身,但要么我的语法错误,要么它不起作用。目前已经通过使用事件处理程序(sooo Windows Forms!!!)
【解决方案2】:

我也希望使用漂亮的命令来完成导航工作。我想出了一个强类型的做事方式。在 XAML、代码隐藏或视图模型中运行良好。

首先,创建一个包含与页面一样多的命令的类。

public class PagesLocator
{
    private Dictionary<string, RelayCommand> commands = new Dictionary<string, RelayCommand>();
    private Frame frame;
    private bool useCurrentFrame;

    public PagesLocator()
    {
        this.useCurrentFrame = true;
    }

    public PagesLocator(Frame frame)
    {
        this.frame = frame;
    }

    public RelayCommand Home
    {
        get { return this.GetCommand("Home", typeof(HomePage)); }
    }

    public RelayCommand Page2
    {
        get { return this.GetCommand("Page2", typeof(Page2)); }
    }

    private RelayCommand GetCommand(string key, Type typeOfPage)
    {
        if (this.commands.ContainsKey(key))
        {
            return this.commands[key];
        }

        var item = new RelayCommand(x => this.GetFrame().Navigate(typeOfPage, x));
        this.commands.Add(key, item);
        return item;
    }
    private Frame GetFrame()
    {
        if (this.frame != null)
        {
            return this.frame;
        }
        else if (this.useCurrentFrame)
        {
            return (Frame)Window.Current.Content;
        }
        else
        {
            throw new InvalidOperationException("Cannot navigate. Current frame is not set.");
        }
    }
}

在应用程序资源中实例化它以具有数据绑定源。

<Application.Resources>
    <common:PagesLocator x:Key="Navigator" />
</Application.Resources>

最后,你可以绑定来自这个源的任何命令。

<Button Content="go to page 2"
    Command="{Binding Page2, Source={StaticResource Navigator}}"
    CommandParameter="extra nav parameter here" />

<AppBarButton Label="page2" Command="{Binding Page2, Source={StaticResource Navigator}}" />

【讨论】:

    猜你喜欢
    • 2015-08-14
    • 2015-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-25
    • 1970-01-01
    • 2014-07-06
    • 1970-01-01
    相关资源
    最近更新 更多