如何为自定义传输控件创建事件

时间:2017-04-19 16:48:47

标签: c# xaml uwp win-universal-app

我正在创建自定义传输控件。在其中,我添加了一个带有MenuFlyout的新按钮来改变视频的质量。那么如何创建在单击特定MenuFlyoutItem时发生的事件。

例如:
如果我使用

<MediaPlayerElement  Name="YoutubePlayer" MaxWidth="640" MaxHeight="360" AreTransportControlsEnabled="True">
    <MediaPlayerElement.TransportControls>
        <QualityTransportControls x:Name="CustomMediaControl" QualityChanged="CustomMediaControl_QualityChanged"/>
    </MediaPlayerElement.TransportControls>
</MediaPlayerElement>

在XAML中,每当我更改质量时都应该调用CustomMediaControl_QualityChanged。可以使用

完成
public event EventHandler QualityChanged
{
    add{}
    remove{}
}

但我不知道在'add'和'remove'中添加什么

这是我的自定义按钮的代码。

<AppBarButton x:Name='QualityButton'
    Style='{StaticResource AppBarButtonStyle}'
    MediaTransportControlsHelper.DropoutOrder='3'>
    <AppBarButton.Flyout>
        <MenuFlyout>
            <MenuFlyoutItem x:Name="Quality144p" Text="144p"/>
            <MenuFlyoutItem x:Name="Quality240p" Text="240p"/>
            <MenuFlyoutItem x:Name="Quality360p" Text="360p"/>
            <MenuFlyoutItem x:Name="Quality480p" Text="480p"/>
            <MenuFlyoutItem x:Name="Quality720p" Text="720p"/>
            <MenuFlyoutItem x:Name="Quality1080p" Text="1080p"/>
        </MenuFlyout>
    </AppBarButton.Flyout>
    <AppBarButton.Icon>
        <SymbolIcon x:Name='QualitySymbol' Symbol='Setting' />
    </AppBarButton.Icon>
</AppBarButton>

1 个答案:

答案 0 :(得分:2)

这个解决方案对我有用:

在ResourceDictionary中添加MediaTransportControls的默认样式 (可在此处找到:C:\ Program Files(x86)\ Windows Kits \ 10 \ DesignTime \ CommonConfiguration \ Neutral \ UAP * your_version_Number * \ Generic,
而不是简单地复制和粘贴整个
<Style TargetType="MediaTransportControls"> ... </Style>标记,可在约16350行找到

将第一行从<Style TargetType="MediaTransportControls">更改为例如<Style TargetType="QualityTransportControls">以定位您的控件。

您需要将您的控件的xaml代码添加到ResourceDictionary,例如在AudioTracksSelectionButton之后(这取决于您希望控件显示的位置)。

<AppBarButton x:Name='AudioTracksSelectionButton'
              Style='{StaticResource AppBarButtonStyle}'
              MediaTransportControlsHelper.DropoutOrder='13'
              Visibility='Collapsed'>
    <AppBarButton.Icon>
        <FontIcon Glyph="&#xED1F;" />
    </AppBarButton.Icon>
</AppBarButton>
<AppBarButton x:Name='QualityButton'
              Style='{StaticResource AppBarButtonStyle}'
              MediaTransportControlsHelper.DropoutOrder='3'>
    <AppBarButton.Flyout>
        <MenuFlyout>
            <MenuFlyoutItem x:Name="Quality144p"
                            Text="144p" />
            <MenuFlyoutItem x:Name="Quality240p"
                            Text="240p" />
        </MenuFlyout>
    </AppBarButton.Flyout>
    <AppBarButton.Icon>
        <SymbolIcon x:Name='QualitySymbol'
                    Symbol='Setting' />
    </AppBarButton.Icon>
</AppBarButton>

然后创建一个新的类,它派生自MediaTransportControls并覆盖OnApplyTemplate(),以便可以检索您的控件,并且您可以手动添加tapped事件。

public sealed class QualityTransportControls: MediaTransportControls
{
    //store the old quality for the custom event
    private int oldQuality = 144;
    private int quality = 144;
    public int Quality
    {
        get { return quality; }
        set {
            //update oldQuality
            oldQuality = quality;
            quality = value;
            //this method is responsible for raising the event
            OnQualityChanged();
        }
    }

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

    protected override void OnApplyTemplate()
    {
        MenuFlyoutItem flyoutItem = GetTemplateChild("Quality144p") as MenuFlyoutItem;
        flyoutItem.Tapped += SetQuality144;

        MenuFlyoutItem flyoutItem2 = GetTemplateChild("Quality240p") as MenuFlyoutItem;
        flyoutItem.Tapped += SetQuality240;

        base.OnApplyTemplate();
    }

    private void SetQuality144(object sender, TappedRoutedEventArgs e)
    {
        Quality = 144;
    }

    private void SetQuality240(object sender, TappedRoutedEventArgs e)
    {
        Quality = 244;
    }

    private EventRegistrationTokenTable<EventHandler<QualityChangedEventArgs>> m_NumberChangedTokenTable = null;

    //this is your custom event which you can use within xaml
    public event EventHandler<QualityChangedEventArgs> QualityChanged
    {
        add
        {
            EventRegistrationTokenTable<EventHandler<QualityChangedEventArgs>>
                .GetOrCreateEventRegistrationTokenTable(ref m_NumberChangedTokenTable)
                .AddEventHandler(value);
        }
        remove
        {
            EventRegistrationTokenTable<EventHandler<QualityChangedEventArgs>>
                .GetOrCreateEventRegistrationTokenTable(ref m_NumberChangedTokenTable)
                .RemoveEventHandler(value);
        }
    }


    internal void OnQualityChanged()
    {
        //here you raise the event for every subscriber
        EventRegistrationTokenTable<EventHandler<QualityChangedEventArgs>>
        .GetOrCreateEventRegistrationTokenTable(ref m_NumberChangedTokenTable)
        .InvocationList?.Invoke(this, new QualityChangedEventArgs(oldQuality, Quality));
    }
}

然后您需要一个QualityChangedEventArgs类,以便您可以向事件添加信息(例如旧的和新的质量)。

public class QualityChangedEventArgs:EventArgs
{
    public int OldQuality { get; set; }
    public int NewQuality { get; set; }

    public QualityChangedEventArgs(int oldValue, int newValue)
    {
        OldQuality = oldValue;
        NewQuality = newValue;
    }
}

现在(在构建之后)您可以像使用其他任何事件一样使用QualityChanged事件,例如Tapped

<local:CustomMediaTransportControls
    QualityChanged="CustomMediaTransportControls_QualityChanged"/>

然后你在codebehind(例如你的MainePage)中实现这样的方法:

private void CustomMediaTransportControls_QualityChanged(object sender, QualityChangedEventArgs e)
{
    //here you can change the quality according to the new quality which is stored in e.NewQuality
}