我正试图在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参考中。我总觉得这令人困惑。非常感谢任何帮助。感谢。
答案 0 :(得分:0)
嗯......据我所知,你没有把任何东西绑定到top.appbar或者父母,所以当它试图看到必须去寻找命令时他并不知道它在哪里。 当你在一个简单的按钮中创建它时,按钮的父级是Bind,不是吗?
答案 1 :(得分:0)
我也希望有很好的命令来完成导航工作。我想出了一种强烈的做事方式。从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.");
}
}
}
在app资源中实例化以获得可绑定数据的源。
<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}}" />