BottomAppBar隐藏了完整窗口MediaElement的部分TransportControls



当MediaElement切换到FullWindow模式时,内部FullWindowMediaRoot将成为其临时主机。当可见时,FullWindowMediaRoot位于普通RootScrollViewer的顶部,即它显示为当前页面的覆盖层,这是预期的行为。

我的问题是BottomAppBar。它的主机是内部的PopupRoot,不幸的是它位于FullWindowMediaRoot之上。因此,当我在允许用户将MediaElement切换到FullWindow的页面上使用BottomAppBar时,用户无法使用MediaElement的控件,因为这些元素几乎完全被仍然可见的BottomAppBar隐藏。

我已经为这个问题花了将近一天的时间,找到了一个对我有效的解决方案。如果有人有更好的答案,我会很感激与大家分享。在那之前,我会在下面为遇到同样问题的人记录我目前的工作解决方案。

我的解决方案使用了一个实现IValueConverter的类,每当MediaElement的IsFullWindow属性更改值时,它就会引发一个事件。

页面初始化程序向转换器的FullWindowStateChanged事件添加一个事件处理程序:

this.isFullWindowConverter.FullWindowStateChanged += this.OnFullWindowStateChanged;

并像这样处理:

/// <summary>
/// Handles the FullWindowStateChanged event of IsFullWindowConverter by adjusting the visibility of the BottomAppBar to the full window
/// state of this page's MediaElement.
/// </summary>
/// <param name="sender">The instance of IsFullWindowConverter raising the event.</param>
/// <param name="e">The parameter is not used.</param>
private void OnFullWindowStateChanged(object sender, EventArgs e)
{
    this.BottomAppBar.Visibility = ((IsFullWindowConverter)sender).IsFullWindow ? Visibility.Collapsed : Visibility.Visible;
}

这里的转换器类别:

namespace Filmit.Win
{
    using System;
    using Windows.UI.Xaml.Data;
    /// <summary>
    /// This converter raises an event when the IsFullWindow property of a MediaElement has changed. The converter is added to the resources of the page that hosts the MediaElement:
    /// <code><local:IsFullWindowConverter x:Key="isFullWindowConverter" x:Name="isFullWindowConverter"/></code>
    /// This converter resource is then bound to the IsFullWindow property of a MediaElement, solely for the event raising effects of the ConvertBack method this converter.
    /// The actual value of the IsFullWindow property is returned as is.
    /// <code><MediaElement IsFullWindow="{Binding RelativeSource={RelativeSource Self}, Path=IsFullWindow, Converter={StaticResource isFullWindowConverter}, Mode=TwoWay}"></code>
    /// The subscriber to the FullWindowStateChanged event checks the IsFullWindow property to get the current full window state of the MediaElement.
    /// </summary>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1603:DocumentationMustContainValidXml", Justification = "XAML Page.Resources declaration.")]
    public class IsFullWindowConverter : IValueConverter
    {
        /// <summary>
        /// Raises the FullWindowStateChanged event. Subscribers check the IsFullWindow property to get the current full windows state.
        /// </summary>
        public event EventHandler<EventArgs> FullWindowStateChanged = null;
        /// <summary>
        /// Gets a value indicating whether the mode of the MediaElement is FullWindow.
        /// </summary>
        public bool IsFullWindow { get; private set; }
        /// <summary>
        /// Required implementation of IValueConverter.Convert, returning the passed in boolean object as a bool.
        /// </summary>
        /// <param name="value">The boolean object.</param>
        /// <param name="targetType">The expected target type.</param>
        /// <param name="parameter">The parameter is not used.</param>
        /// <param name="language">The parameter is not used.</param>
        /// <returns>The passed in boolean object as a bool.</returns>
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            bool? isFullWindow = value as bool?;
            this.IsFullWindow = isFullWindow.HasValue ? isFullWindow.Value : false;
            return this.IsFullWindow;
        }
        /// <summary>
        /// This implementation of IValueConverter.ConvertBack is called when the IsFullWindow property of the MediaElement has changed its value.
        /// It raises the FullWindowStateChanged event and returns the passed in boolean object as a bool.
        /// </summary>
        /// <param name="value">The boolean object.</param>
        /// <param name="targetType">The expected target type.</param>
        /// <param name="parameter">The parameter is not used.</param>
        /// <param name="language">The parameter is not used.</param>
        /// <returns>The passed in boolean object as a bool.</returns>
        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            bool? isFullWindow = value as bool?;
            this.IsFullWindow = isFullWindow.HasValue ? isFullWindow.Value : false;
            if (this.FullWindowStateChanged != null)
            {
                this.FullWindowStateChanged(this, new EventArgs());
            }
            return this.IsFullWindow;
        }
    }
}

如果您正在创建一个UWP应用程序,我认为您可以在Grid中放置一个AppBar,并将其定位到页面底部。这也会解决你的问题。但如果你正在使用windows 8.1应用程序,这种方法将不起作用。

XAML:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
     <MediaElement x:Name="MyMedia" Source="Assets/Sofia Jannok-Liekkas.wma" AreTransportControlsEnabled="True" />
    <AppBar  VerticalAlignment="Bottom">
        <CommandBar>
            <CommandBar.Content>
                <Grid/>
            </CommandBar.Content>
            <AppBarButton Icon="Accept" Label="appbarbutton"/>
            <AppBarButton Icon="Cancel" Label="appbarbutton"/>
            <AppBarButton Content="Maximize" VerticalAlignment="Center" HorizontalAlignment="Center"  Click="maximize"/>
        </CommandBar>
    </AppBar>
</Grid>

C#:

 public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }
        public void maximize(object sender, RoutedEventArgs e)
        {
            MyMedia.IsFullWindow = !MyMedia.IsFullWindow;
        }
    }

无论如何,你的解决方案都能解决问题。感谢您的分享。

相关内容

  • 没有找到相关文章

最新更新