如何禁用Windows 8/WinRT应用栏?

11
我的目标是只在特定情况下提供AppBar。我尝试通过创建一个AppBar,但在该情况出现之前将其禁用来实现这一点。然而,如果您将AppBar上的“IsEnabled”属性设置为“False”,当您启动应用程序并右键单击(通常会打开AppBar)时,应用程序会崩溃。这是框架中的错误吗?禁用AppBar的正确方法是什么?
编辑:当您将“Visibility”设置为“Collapsed”时,也会发生此情况。
更多信息:我正在通过Visual Studio调试器运行它,但是一个单独的“Visual Studio Just-In-Time Debugger”窗口弹出,显示消息“在App.exe [2596]中发生未处理的win32异常。”一个警告框弹出在顶部,上面写着“调试器已附加到App.exe,但未配置为调试此未处理的异常。要调试此异常,请分离当前调试器。”
EDIT 2: 不仅仅是我的代码有问题,如果你只是在Microsoft自己的AppBarControl项目中添加IsEnabled="False",它也会崩溃(可以在此处找到:http://code.msdn.microsoft.com/windowsapps/XAML-AppBar-control-sample-2aa1cbb4
EDIT 3: @G. Andrew Duthie - devhammer提供了我正在使用的答案。我只想补充一点,最好使用this.BottomAppBar = null来禁用它,而不是设置IsEnabledVisibility属性。如果你只是将Visibility设置为Collapsed,那么当你右键单击时,应用程序仍然认为存在一个AppBar,即使它不可见,所以你的下一个普通单击将被解释为通常关闭AppBar的单击,因此你必须再次单击才能实际执行你尝试的操作。

3
“the application crashes”是什么意思?它是否在框架中崩溃?还是在你的代码中崩溃?你有调用堆栈吗?是否抛出异常?异常是什么(和消息是什么)? - James McNellis
我觉得它在框架中崩溃了。我正在通过Visual Studio调试器运行它,但是一个单独的“Visual Studio即时调试器”窗口弹出,显示消息“App.exe [2596]发生了一个未处理的win32异常。”然后又弹出一个警告框,上面写着“调试器已连接到App.exe,但未配置为调试此未处理的异常。要调试此异常,请分离当前调试器。” - jokeefe
我认为我们需要更多的上下文来找出问题所在。你能发布你的AppBar xaml吗? - N_A
你可以等几天,看看 Windows 8 的发布版本是否也会抛出异常。 - Emond
1
@mydogisbox 这不仅仅是我的代码的问题。即使在微软自己的示例AppBarControl项目中,只要将IsEnabled="False"添加到AppBar中,它也会崩溃(在此处找到:http://code.msdn.microsoft.com/windowsapps/XAML-AppBar-control-sample-2aa1cbb4)。 - jokeefe
5个回答

8

我已经尝试了一段时间(使用IsEnabled和将Visibility属性设置为Visibility.Collapsed),唯一成功禁用AppBar而不引发异常的方法是先显示AppBar。一旦显示了AppBar,将IsEnabled设置为false或将Visibility设置为Visibility.Collapsed就不再抛出异常。

但是,如果你以编程方式创建AppBar,像这样:

myAppBar = new AppBar();
StackPanel sp = new StackPanel();
sp.Orientation = Orientation.Horizontal;
Button myButton = new Button();
myButton.Content = "Click Me";
sp.Children.Add(myButton);
myAppBar.Content = sp;

不过,在你第一次需要它之前不要将其添加到 Page.BottomAppBar,这样就不会出现异常。

我使用了一个带有以下处理程序的按钮进行测试:

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    if (this.BottomAppBar == null)
    {
        this.BottomAppBar = myAppBar;
    }
    else {
        this.BottomAppBar = null;
    }
}

当应用程序首次加载时,如果尝试调用AppBar,则不会发生任何事情。单击按钮(将AppBar添加到Page.BottomAppBar),然后调用AppBar将显示AppBar。再次单击按钮,AppBar将不再显示(尽管myAppBar仍然实例化并准备好在下次需要时使用)。
希望这有所帮助!

1
这个工作完美。谢谢!我发现最好使用this.BottomAppBar = null来禁用它,而不是设置IsEnabledVisibility属性。如果你只是将Visibility设置为Collapsed,那么当你右键单击时,应用程序仍然认为存在一个AppBar,即使它不可见,所以你的下一个常规单击将被解释为通常解除AppBar的单击,因此你必须再点击一次才能实际执行你尝试的操作。再次感谢您的帮助! - jokeefe
尝试加载在xaml文件中定义的应用栏资源对象失败了。然而,我成功地使用了纯代码而没有任何xaml资源。 - Scott Nimrod

4

如果您仍然想在XAML中定义AppBar,您可以在代码后台程序atically关闭它。在XAML中创建底部AppBar:

<Page.BottomAppBar>
    <AppBar Name="MyAppBar" Opened="AppBarOpened">
        ...
    </AppBar>
</Page.BottomAppBar>

然后,在C#代码中:

private void AppBarOpened(object sender, object e)
{
    if ( CanAppBarOpen() == false)
    {
        MyAppBar.IsOpen = false;
    }
}

你需要实现自己的检查"CanAppBarOpen()"


2
您可以通过处理AppBar的“opened”事件来实现这样的操作。
在XAML中:
<Page.BottomAppbar>
   <AppBar IsEnabled="False" Visibility="Collapsed" Opened="bottomappbar_opened_event">
</Page.BottomAppbar>

在C#代码中:
 private void bottomappbar_opened_event(object sender, object e)
 {
     if (!this.BottomAppBar.IsEnabled)
     {
         if (this.BottomAppBar.IsOpen)
         this.BottomAppBar.IsOpen = false;
     }
 }

2

您可以使用WinRT XAML Toolkit中的CustomAppBar。它可以通过多种方式禁用 - 您可以将其CanOpen或CanDismiss属性绑定到阻止它出现或消失的操作,这可能是您想要的。


1
当然可以。他/她希望根据条件使应用栏工作或不工作,而CustomAppBar正好提供了这一点,并且不会崩溃。我之所以创建它,正是由于本机AppBar的限制/问题。 - Filip Skakun
非常感谢您的建议,@Filip Skakun。如果我无法使G. Andrew Duthie - devhammer提供的解决方案起作用,我肯定会选择这种方法。下次遇到类似问题时,我会再次查看您的库。 - jokeefe

0

1. 在 XAML 文件中为您的 FlipView 控件添加选择更改事件:

<FlipView SelectionChanged="MyFlipView_SelectionChanged" />

2. 在您的XAML代码后台文件中添加此类成员变量:

Dictionary<object, Tuple<AppBar, AppBar>> _appbarDictionary = new Dictionary<object, Tuple<AppBar, AppBar>>();

3. 在这里实现FlipView的选择更改处理程序:

private void MyFlipView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var flipView = sender as FlipView;

    BuildPageAppBarDictionary();

    InitializeAppBar(flipView);
    NullOtherAppBars(flipView);
}

添加以下方法: private void BuildPageAppBarDictionary() { _appbarDictionary.Clear(); foreach (var item in MyFlipView.Items) { var page = item as Page; Tuple appbars = new Tuple(page.TopAppBar, page.BottomAppBar); _appbarDictionary.Add(page, appbars); } } private void InitializeAppBar(FlipView flipView) { if (_appbarDictionary.Count > 0) { var currentPage = flipView.SelectedItem as Page; currentPage.TopAppBar = _appbarDictionary[currentPage].Item1; currentPage.BottomAppBar = _appbarDictionary[currentPage].Item2;
if (currentPage.TopAppBar != null) { currentPage.TopAppBar.IsEnabled = true; }
if (currentPage.BottomAppBar != null) { currentPage.BottomAppBar.IsEnabled = true; } } } private void NullOtherAppBars(FlipView flipView) { foreach (var item in MyFlipView.Items) { if (item != flipView.SelectedItem) { var page = item as Page; page.TopAppBar = null; page.BottomAppBar = null; } } }
请原谅片段格式问题。我尽力将示例格式最好地呈现在此页上。

混合使用列表符和代码不太好(开始在此发布时也遇到过同样的问题 :-)) - kleopatra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接