Windows runtime BottomAppBar隐藏完整窗口MediaElement的部分TransportControl

Windows runtime BottomAppBar隐藏完整窗口MediaElement的部分TransportControl,windows-runtime,windows-store-apps,winrt-xaml,Windows Runtime,Windows Store Apps,Winrt Xaml,当MediaElement切换到FullWindow模式时,内部FullWindowMediaRoot将成为其临时主机。当可见时,FullWindowMediaRoot位于普通RootScrollViewer的顶部,即显示为覆盖当前页面,这是预期的行为 我的问题是底部的AppBar。它的宿主是内部populot,不幸的是它位于FullWindowMediaRoot的顶部。因此,当我在允许用户将MediaElement切换到FullWindow的页面上使用BottomAppBar时,用户无法使用M

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

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

我为这个问题花了将近一天的时间,终于找到了一个适合我的解决方案。如果有人有更好的答案,我将非常感谢分享。在此之前,我将在下面为遇到相同问题的任何人记录我当前的工作解决方案

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

页面初始化器将事件处理程序添加到转换器的FullWindowsStateChanged事件:

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;
}
//
///通过将底部AppBar的可见性调整为完整窗口,处理IsFullWindowConverter的FullWindowsStateChanged事件
///此页的MediaElement的状态。
/// 
///引发事件的IsFullWindowConverter实例。
///未使用该参数。
FullWindowsStateChanged上的私有void(对象发送方,事件参数e)
{
this.BottomAppBar.Visibility=((IsFullWindowConverter)发送器).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;
        }
    }
}
it.Win
{
使用制度;
使用Windows.UI.Xaml.Data;
/// 
///当MediaElement的IsFullWindow属性发生更改时,此转换器将引发一个事件。转换器将添加到承载MediaElement的页面的资源中:
///
///然后将此转换器资源绑定到MediaElement的IsFullWindow属性,仅用于此转换器的ConvertBack方法的事件引发效果。 ///IsFullWindow属性的实际值按原样返回。 ///
///FullWindowsStateChanged事件的订阅服务器检查IsFullWindow属性以获取MediaElement的当前完整窗口状态。 /// [System.Diagnostics.CodeAnalysis.SuppressMessage(“StyleCop.CSharp.DocumentationRules”,“SA1603:DocumentationMustContaineValidXML”,justionment=“XAML Page.Resources声明”)] 公共类IsFullWindowConverter:IValueConverter { /// ///引发FullWindowsStateChanged事件。订阅服务器检查IsFullWindow属性以获取当前的完整windows状态。 /// 公共事件EventHandler FullWindowsStateChanged=null; /// ///获取一个值,该值指示MediaElement的模式是否为FullWindow。 /// public bool IsFullWindow{get;private set;} /// ///IValueConverter.Convert的必需实现,将传入的布尔对象作为布尔值返回。 /// ///布尔对象。 ///预期的目标类型。 ///未使用该参数。 ///未使用该参数。 ///作为布尔值传入的布尔对象。 公共对象转换(对象值、类型targetType、对象参数、字符串语言) { bool?isFullWindow=值为bool?; this.IsFullWindow=IsFullWindow.HasValue?IsFullWindow.Value:false; 返回此.IsFullWindow; } /// ///当MediaElement的IsFullWindow属性更改其值时,将调用IValueConverter.ConvertBack的此实现。 ///它引发FullWindowsStateChanged事件,并将传入的布尔对象作为布尔值返回。 /// ///布尔对象。 ///预期的目标类型。 ///未使用该参数。 ///未使用该参数。 ///作为布尔值传入的布尔对象。 公共对象转换回(对象值、类型targetType、对象参数、字符串语言) { bool?isFullWindow=值为bool?; this.IsFullWindow=IsFullWindow.HasValue?IsFullWindow.Value:false; 如果(this.fullWindowsStateChanged!=null) { this.fullWindowsStateChanged(this,new EventArgs()); } 返回此.IsFullWindow; } } }
如果您正在创建一个UWP应用程序,我认为您可以在
网格中放置一个
AppBar
,并将其定位到页面底部。这也会解决你的问题。但是,如果您正在使用windows 8.1应用程序,此方法将不起作用

XAML:


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

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

XAML:


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

我的应用程序是一个UWP应用程序,因此可以自由定位CommandBar通常是一个出路。我的应用程序包含表单,因此平板电脑用户需要触摸键盘。所以我坚持要让这个应用程序与BottomAppBar一起工作。Microsoft:“如果当触摸键盘或软输入面板(SIP)出现时,命令栏必须对用户保持可见,则您可以将其分配给页面的BottomAppBar属性,当SIP出现时,命令栏将移动以保持可见。”谢谢您的回答!如果键盘没有问题,您的解决方案是
<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>
 public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        public void maximize(object sender, RoutedEventArgs e)
        {
            MyMedia.IsFullWindow = !MyMedia.IsFullWindow;
        }
    }