建立自訂傳輸控制項

MediaPlayerElement 具有可自訂的 XAML 傳輸控制項,以管理 Windows 應用程式內音訊和視訊內容的控制項。 在這裡,我們示範如何自訂 MediaTransportControls 範本。 我們將向您展示如何使用溢出選單、新增自訂按鈕和修改滑桿。

Important APIMediaPlayerElementMediaPlayerElement.AreTransportControlsEnabledMediaTransportControls

在開始之前,您應該熟悉 MediaPlayerElement 和 MediaTransportControls 類別。 如需詳細資訊,請參閱 MediaPlayerElement 控制項指南。

提示

本主題中的範例基於媒體傳輸控制項範例。 您可以下載範例來查看並執行完整的程式碼。

注意

MediaPlayerElement 僅適用於 Windows 10 版本 1607 及更高版本。 如果您正在為早期版本的 Windows 10 開發應用程式,則需要改用 MediaElement。 此頁面上的所有範例也都使用 MediaElement

何時應該自訂範本?

MediaPlayerElement 具有內建的傳輸控制項,其設計目的是在大部分的視訊和音訊播放應用程式中都能夠順利運作。 它們由 MediaTransportControls 類別提供,包括用於播放、停止和導航媒體、調整音量、切換全螢幕、投射到第二個裝置、啟用字幕、切換音軌和調整播放速率的按鈕。 MediaTransportControls 具有屬性,可讓您控制是否顯示並啟用每個按鈕。 您也可以設定 IsCompact 屬性,以指定控制項是否顯示在一個資料列或兩個資料列中。

不過,在某些情況下,您可能需要進一步自訂控制項的外觀或變更其行為。 以下列出一些範例:

  • 變更圖示、滑桿行為和色彩。
  • 將較不常用的命令按鈕移至溢位功能表。
  • 變更當控制項重設大小時,命令卸除的順序。
  • 提供不在預設集中的命令按鈕。

注意

如果螢幕上沒有足夠的空間,螢幕上可見的按鈕將按照預先定義的順序從內建傳輸控制項中刪除。 若要變更此順序或放置不適合溢出選單的命令,您將需要自訂控制項。

您可以透過修改預設範本來自訂控制項的外觀。 若要修改控制項的行為或新增指令,您可以建立衍生自 MediaTransportControls 的自訂控制項。

提示

可自訂的控制項範本是 XAML 平台的強大功能,但也有一些後果值得您考慮。 當您自訂範本時,它將成為應用程式的靜態部分,因此不會收到 Microsoft 對範本進行的任何平台更新。 如果 Microsoft 進行了範本更新,您應該採用新範本並重新修改它,以便獲得更新範本的好處。

範本結構

ControlTemplate 是預設樣式的一部分。 您可以將此預設樣式複製到您的專案中進行修改。 ControlTemplate 分成與其他 XAML 控制項範本類似的部分。

  • 範本的第一部分包含 MediaTransportControls 的各個元件的樣式定義。
  • 第二個區段會定義 MediaTransportControls 所使用的各種視覺狀態。
  • 第三部分包含將各種 MediaTransportControls 元素保存在一起的網格,並定義元件的佈局方式。

注意

如需修改範本的詳細資訊,請參閱控制範本。 您可以使用文字編輯器或 IDE 中的類似編輯器,來開啟 (Program Files)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP(SDK version)\Generic 中的 XAML 檔案。 每個控制項的預設樣式和範本在 generic.xaml 檔案中定義。 您可以透過搜尋「MediaTransportControls」在 generic.xaml 中找到 MediaTransportControls 範本。

在以下部分中,您將了解如何自訂傳輸控制項的幾個主要元素:

  • Slider:允許使用者拖曳他們的媒體,同時顯示進度
  • CommandBar:包含所有按鈕。 如需詳細資訊,請參閱 MediaTransportControls 參考主題的剖析一節。

自訂傳輸控制項

如果只想修改 MediaTransportControls 的外觀,則可以建立預設控制項樣式和範本的副本,然後對其進行修改。 但是,如果您也想要新增或修改控制項的功能,則需要建立一個衍生自 MediaTransportControls 的新類別。

重新範本控制件

自訂 MediaTransportControls 預設樣式與範本

  1. 將預設樣式從 MediaTransportControls 樣式和範本複製到專案中的 ResourceDictionary 中。
  2. 為樣式指定一個 x:Key 值來識別它,如下所示。
<Style TargetType="MediaTransportControls" x:Key="myTransportControlsStyle">
    <!-- Style content ... -->
</Style>
  1. 將 MediaPlayerElement 與 MediaTransportControls 新增至您的 UI。
  2. 將 MediaTransportControls 元素的 Style 屬性設定為自訂 Style 資源,如下所示。
<MediaPlayerElement AreTransportControlsEnabled="True">
    <MediaPlayerElement.TransportControls>
        <MediaTransportControls Style="{StaticResource myTransportControlsStyle}"/>
    </MediaPlayerElement.TransportControls>
</MediaPlayerElement>

如需修改樣式和範本的詳細資訊,請參閱 設定控制項控制項範本的樣式。

建立衍生控制項

若要新增或修改傳輸控制項的功能,您必須建立衍生自 MediaTransportControls 的新類別。 名為 CustomMediaTransportControls 衍生類別會顯示在媒體傳輸控制項範例和此頁面的其餘範例中。

建立衍生自 MediaTransportControls 的新類別

  1. 將新的類別檔案新增到您的專案。
    • 在 Visual Studio 中,選擇專案>新增類別。 [新增項目] 對話方塊隨即開啟。
    • 在新增項目對話方塊中,輸入類別檔案的名稱,然後按一下新增。 (在媒體傳輸控制項範例中,類別名為 CustomMediaTransportControls。)
  2. 修改類別程序代碼,以衍生自 MediaTransportControls 類別。
public sealed class CustomMediaTransportControls : MediaTransportControls
{
}
  1. MediaTransportControls 的預設樣式複製到專案中的 ResourceDictionary 中。 這是您修改的樣式和範本。 (在媒體傳輸控制項範例中,建立了一個名為「Themes」的新資料夾,並在其中新增了一個名為 generic.xaml 的 ResourceDictionary 檔案。)
  2. 將樣式的 TargetType 變更為新的自訂控制項類型。 (在範例中,TargetType 已變更為 local:CustomMediaTransportControls。)
xmlns:local="using:CustomMediaTransportControls">
...
<Style TargetType="local:CustomMediaTransportControls">
  1. 設定自訂類別的 DefaultStyleKey。 這告訴您的自訂類別使用 TargetType 為 local:CustomMediaTransportControls 的 Style。
public sealed class CustomMediaTransportControls : MediaTransportControls
{
    public CustomMediaTransportControls()
    {
        this.DefaultStyleKey = typeof(CustomMediaTransportControls);
    }
}
  1. 將 MediaPlayerElement 新增至 XAML 標記,並將自訂傳輸控制項新增至其中。 要注意的是,用於隱藏、顯示、停用和啟用預設按鈕的 API 仍然適用於自訂範本。
<MediaPlayerElement Name="MediaPlayerElement1" AreTransportControlsEnabled="True" Source="video.mp4">
    <MediaPlayerElement.TransportControls>
        <local:CustomMediaTransportControls x:Name="customMTC"
                                            IsFastForwardButtonVisible="True"
                                            IsFastForwardEnabled="True"
                                            IsFastRewindButtonVisible="True"
                                            IsFastRewindEnabled="True"
                                            IsPlaybackRateButtonVisible="True"
                                            IsPlaybackRateEnabled="True"
                                            IsCompact="False">
        </local:CustomMediaTransportControls>
    </MediaPlayerElement.TransportControls>
</MediaPlayerElement>

現在您可以修改控制項樣式和範本以更新自訂控制項的外觀,並修改控制項程式碼以更新其行為。

使用溢位功能表

您可以將 MediaTransportControls 指令按鈕移至溢位選單中,以便隱藏不常用的指令,直到使用者需要它們為止。

在 MediaTransportControls 範本中,命令按鈕包含在 CommandBar 元素中。 命令列具有主要命令和輔助命令的概念。 主要命令是預設出現在控制項中且始終可見的按鈕 (除非停用按鈕、隱藏按鈕或沒有足夠的空間)。 次要命令會顯示在使用者按下省略號 (…) 按鈕時出現的溢位選單。 有關詳細資訊,請參閱應用程式欄和命令列一文。

若要將元素從命令列主要命令移至溢位選單,您需要編輯 XAML 控制項範本。

將命令移至溢位功能表:

  1. 在控制項範本中,找到名為 MediaControlsCommandBar 的 CommandBar 元素。
  2. SecondCommands 部分新增至 CommandBar 的 XAML。 將其放在 PrimaryCommands 的結束標記之後。
<CommandBar x:Name="MediaControlsCommandBar" ... >  
  <CommandBar.PrimaryCommands>
...
    <AppBarButton x:Name='PlaybackRateButton'
                    Style='{StaticResource AppBarButtonStyle}'
                    MediaTransportControlsHelper.DropoutOrder='4'
                    Visibility='Collapsed'>
      <AppBarButton.Icon>
        <FontIcon Glyph="&#xEC57;"/>
      </AppBarButton.Icon>
    </AppBarButton>
...
  </CommandBar.PrimaryCommands>
<!-- Add secondary commands (overflow menu) here -->
  <CommandBar.SecondaryCommands>
    ...
  </CommandBar.SecondaryCommands>
</CommandBar>
  1. 若要使用命令填入功能表,請將所需 AppBarButton 物件的 XAML 從 PrimaryCommands 剪下並貼到 SecondaryCommands。 在此範例中,我們將 PlaybackRateButton 移至溢出選單。

  2. 將標籤新增至按鈕並移除樣式資訊,如下所示。 由於溢位選單由文字按鈕組成,因此您必須在按鈕上新增文字標籤,並刪除設定按鈕高度和寬度的樣式。 否則,它不會出現在溢位功能表中。

<CommandBar.SecondaryCommands>
    <AppBarButton x:Name='PlaybackRateButton'
                  Label='Playback Rate'>
    </AppBarButton>
</CommandBar.SecondaryCommands>

重要

您仍然必須讓按鈕顯示並加以啟用,才能在溢位功能表中使用它。 在此範例中,除非 IsPlaybackRateButtonVisible 屬性為 true,否則 PlaybackRateButton 元素在溢出選單中不可見。 除非 IsPlaybackRateEnabled 屬性為 true,否則不會啟用它。 設定這些屬性會顯示在上一節中。

新增自訂按鈕

您可能想要自訂 MediaTransportControls 的原因之一是向控制項新增自訂命令。 無論將其新增為主命令或輔助命令,建立命令按鈕和修改其行為的過程都是相同的。 在媒體傳輸控制項範例中,主要命令中新增了「評級」按鈕。

新增自訂命令按鈕

  1. 建立一個 AppBarButton 物件並將其新增至控制項範本中的 CommandBar 中。
<AppBarButton x:Name="LikeButton"
              Icon="Like"
              Style="{StaticResource AppBarButtonStyle}"
              MediaTransportControlsHelper.DropoutOrder="3"
              VerticalAlignment="Center" />

您必須將它新增至適當位置的 CommandBar。 (關於詳細資訊,請參閱使用溢出選單部分。) 它在 UI 中的定位方式取決於按鈕在標記中的位置。 比方說,如果您想要此按鈕顯示為主要命令中的最後一個元素,則將它新增於主要命令清單的最尾端。

您也可以自訂此按鈕的圖示。 如需詳細資訊,請參閱 AppBarButton 參考。

  1. OnApplyTemplate 重寫中,從範本取得按鈕並為其 Click 事件註冊一個處理程序。 這段程式碼放在 CustomMediaTransportControls 類別中。
public sealed class CustomMediaTransportControls :  MediaTransportControls
{
    // ...

    protected override void OnApplyTemplate()
    {
        // Find the custom button and create an event handler for its Click event.
        var likeButton = GetTemplateChild("LikeButton") as Button;
        likeButton.Click += LikeButton_Click;
        base.OnApplyTemplate();
    }

    //...
}
  1. 將程式代碼新增至 Click 事件處理程式,以執行按鍵時所發生的動作。 這是該類別的完整程式碼。
public sealed class CustomMediaTransportControls : MediaTransportControls
{
    public event EventHandler< EventArgs> Liked;

    public CustomMediaTransportControls()
    {
        this.DefaultStyleKey = typeof(CustomMediaTransportControls);
    }

    protected override void OnApplyTemplate()
    {
        // Find the custom button and create an event handler for its Click event.
        var likeButton = GetTemplateChild("LikeButton") as Button;
        likeButton.Click += LikeButton_Click;
        base.OnApplyTemplate();
    }

    private void LikeButton_Click(object sender, RoutedEventArgs e)
    {
        // Raise an event on the custom control when 'like' is clicked.
        var handler = Liked;
        if (handler != null)
        {
            handler(this, EventArgs.Empty);
        }
    }
}

修改滑桿

MediaTransportControls 的「搜尋」控制項由 Slider 元素提供。 自訂它的一種方法是更改搜尋行為的粒度。

預設搜尋滑桿分為 100 個部分,因此搜尋行為僅限於這麼多部分。 您可以透過從 MediaPlayerElement.MediaPlayer 上的 MediaOpened 事件處理程序中的 XAML 視覺化樹中取得滑桿來變更搜尋滑桿的細微差別。 此範例示範如何使用 VisualTreeHelper 取得對滑桿的引用,然後如果媒體長度超過 120 分鐘,則如何將滑桿的預設步進頻率從 1% 變更為 0.1% (1000 步)。 MediaPlayerElement 名為 MediaPlayerElement1

protected override void OnNavigatedTo(NavigationEventArgs e)
{
  MediaPlayerElement1.MediaPlayer.MediaOpened += MediaPlayerElement_MediaPlayer_MediaOpened;
  base.OnNavigatedTo(e);
}

private void MediaPlayerElement_MediaPlayer_MediaOpened(object sender, RoutedEventArgs e)
{
  FrameworkElement transportControlsTemplateRoot = (FrameworkElement)VisualTreeHelper.GetChild(MediaPlayerElement1.TransportControls, 0);
  Slider sliderControl = (Slider)transportControlsTemplateRoot.FindName("ProgressSlider");
  if (sliderControl != null && MediaPlayerElement1.NaturalDuration.TimeSpan.TotalMinutes > 120)
  {
    // Default is 1%. Change to 0.1% for more granular seeking.
    sliderControl.StepFrequency = 0.1;
  }
}