Как отключить Windows 8/WinRT AppBar?

Моя цель - иметь только AppBar, доступный при определенных обстоятельствах. Я пытаюсь сделать это, создав AppBar, но оставив его отключенным, пока это обстоятельство не возникнет. Однако, если вы установите атрибут IsEnabled в AppBar на False, при запуске приложения и щелчке правой кнопкой мыши (который обычно открывает AppBar) приложение сбой. Это ошибка в рамках? Каким образом можно отключить AppBar?

EDIT: Это также происходит, когда вы устанавливаете Visibility в Collapsed.

Дополнительная информация: я запускаю его через отладчик Visual Studio, но открывается отдельное окно "Отладка Visual Studio Just-In-Time Debugger" с сообщением "Необработанное исключение win32 произошло в App.exe [2596]." Вместо этого появляется надпись "Отладчик прикреплен к App.exe, но не настроен для отладки этого необработанного исключения. Чтобы отладить это исключение, отсоедините текущий отладчик".

EDIT 2: Это не только мой код. Он также выйдет из строя, если вы просто добавите IsEnabled="False" в AppBar в собственный образец проекта AppBarControl из Microsoft (здесь: http://code.msdn.microsoft.com/windowsapps/XAML-AppBar-control-sample-2aa1cbb4)

ИЗМЕНИТЬ 3: @G. Andrew Duthie - devhammer предоставил ответ, который я использую. Я просто хотел добавить, что я нашел, что лучше использовать this.BottomAppBar = null, чтобы отключить его, а не устанавливать свойства IsEnabled или Visibility. Если вы просто установили Visibility в Collapsed, тогда при щелчке правой кнопкой мыши приложение все еще считает, что AppBar присутствует, даже если он не отображается, поэтому следующий очередной щелчок будет интерпретироваться как щелчок, который обычно отклоняет AppBar, поэтому вам придется нажать второй раз, чтобы выполнить действие, которое вы пытались выполнить.

Ответ 1

Я играл с этим немного (используя как IsEnabled, так и устанавливая свойство Visibility для Visibility.Collapsed), и единственным способом, который я мог бы успешно отключить AppBar без повышения исключения, было показать AppBar первый. Как только AppBar будет показан, установите значение IsEnabled равным false или установите параметр Visibility to 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;

но не добавляйте его на страницу .BottomAppBar до первого раза, когда вам это нужно, вы не получите исключение.

Я тестировал с помощью кнопки со следующим обработчиком:

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

Когда приложение загружается в первый раз, если вы пытаетесь вызвать AppBar, ничего не происходит. Нажмите кнопку (которая добавляет AppBar на страницу .BottomAppBar), и при вызове AppBar отобразится AppBar. Нажмите кнопку еще раз, и AppBar больше не отображается (хотя myAppBar все еще создается и готов, когда вам это нужно).

Надеюсь, что это поможет!

Ответ 2

Если вы хотите по-прежнему хотеть определить свой AppBar в XAML, вы можете программно закрыть AppBar в коде позади. В XAML создайте нижний AppBar:

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

Затем в коде С# позади:

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

Вам нужно будет выполнить собственную проверку для "CanAppBarOpen()"

Ответ 3

Вы можете использовать CustomAppBar из WinRT XAML Toolkit. Его можно отключить несколькими способами - вы можете привязать его свойства CanOpen или CanDismiss, чтобы он не появлялся или не уходил, что может быть тем, что вы хотите.

Ответ 4

Вы можете сделать это, выполнив открытое событие AppBar

В XAML:

<Page.BottomAppbar>
   <AppBar IsEnabled="False" Visibility="Collapsed" Opened="bottomappbar_opened_event">
</Page.BottomAppbar>

В коде С#:

 private void bottomappbar_opened_event(object sender, object e)
 {
     if (!this.BottomAppBar.IsEnabled)
     {
         if (this.BottomAppBar.IsOpen)
         this.BottomAppBar.IsOpen = false;
     }
 }

Ответ 5

1. Добавьте в файл управления xaml выбранное событие с изменением:

<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<AppBar, AppBar> appbars = new Tuple<AppBar, AppBar>(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 в MyFlipView.Items)       {           if (item!= flipView.SelectedItem)           {               var page = item as Page;

                page.TopAppBar = null;
                page.BottomAppBar = null;
            }
        }
    }
    

Пожалуйста, простите проблемы форматирования фрагмента. Я попытался сделать примерный формат на эту страницу как можно лучше.