Wpf Visual Brush Визуальная привязка к MediaElement

У меня есть вопрос о привязке визуальной кисти к визуальной. Если я определю это в XAML, это будет работать. Если я определяю то же самое программно, то это не работает. Вот пример.

 <Window x:Class="WpfApp1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            x:Name="MyWindow"
            Title="MainWindow" Height="350" Width="525">
    <Grid >
        <Rectangle Height="299" Width="400" Stroke="Red" StrokeThickness="20" >
            <Rectangle.Fill>
                <VisualBrush TileMode="None" Stretch="UniformToFill" Visual="{Binding  ElementName=MyWindow, Path=Stuff}">
                    <!--<VisualBrush.Visual>
                            <MediaElement Source="MovingImages_2017-03-10-05-02-22.wmv" LoadedBehavior="Play" />
                        </VisualBrush.Visual>-->
                </VisualBrush>
            </Rectangle.Fill>
        </Rectangle>
    </Grid>
</Window>

Я пробовал следующее свойство как визуальный и медиа элемент.

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        public Visual Stuff { get; set; }

        public MainWindow()
        {
            InitializeComponent();

            MediaElement me = new MediaElement();
            me.Source = new Uri("MovingImages_2017-03-10-05-02-22.wmv", UriKind.Relative);
            me.LoadedBehavior = MediaState.Play;


            this.Stuff = (Visual) me;
        }
    }
}

Редактировать 3. Я обнаружил ошибки привязки, и это связано. Оказывается в Live Visual Tree / Live Property Explorer. Это просто не появляется.

Кто-нибудь знает почему?

3 ответа

Кажется, есть проблема при связывании Visuals и VisualBrushes. В этом случае я бы предложил побороть вашу проблему так, чтобы она также лучше подходила для разделения MVVM. Вместо привязки визуала создайте визуал в XAML и свяжите его со свойством источника визуала. Ваш XAML будет:

<Rectangle Height="299" Width="400" Stroke="Red" StrokeThickness="20">
        <Rectangle.Fill>
            <VisualBrush TileMode="None" Stretch="UniformToFill">
                <VisualBrush.Visual>
                        <MediaElement Source="{Binding Path=MovieUri, ElementName=MyWindow}" LoadedBehavior="Play" />
                    </VisualBrush.Visual>
            </VisualBrush>
        </Rectangle.Fill>
    </Rectangle>

И ваш код позади:

public Uri MovieUri { get; set; }

    public MainWindow()
    {
        MovieUri = new Uri("movie.mp4", UriKind.Relative);

        InitializeComponent();            
    }

Невозможно использовать привязку к чему-либо, содержащему медиа-элемент, и заставить его воспроизводиться.

Обходной путь - вы подписываетесь на событие изменения свойства модели представления для объекта, содержащего медиа-элемент. Когда он меняется, вы добавляете объект программно. Затем медиа-элемент будет отображаться и воспроизводиться.

Кажется, это потому, что ваш Stuff свойство не уведомляет об этом изменилось. У вас есть три варианта решения:

1) Реализуйте интерфейс INotifyPropertyChanged в своем классе MainWindow и при установке Stuff свойство вызывает событие PropertyChanged.

2) Определите Stuff свойство как DependencyProperty, которому присуще уведомление об изменении свойства (так как ваш класс является DependencyObject)

3) Назначьте значение свойства перед вызовом InitializeComponent. Очевидно, это будет работать только один раз во время инициализации.

public MainWindow()
{
    Stuff = new MediaElement
    {
        Source = new Uri("MovingImages_2017-03-10-05-02-22.wmv", UriKind.Relative),
        LoadedBehavior = MediaState.Play
    };

    InitializeComponent();
}

Это два доступных метода участия свойства в игре Binding.

Другие вопросы по тегам