-1

I have a question about binding to a visual brush visual. If I define it in XAML it works. If I define the the same thing programmatically then it does not work. Here is an example.

 <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>

I have tried the following property as a visual and a media element.

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;
        }
    }
}

Edit 3. I have turned up binding errors and it is being bound. It turns up in the Live Visual Tree / Live property Explorer. It just does not show up.

Does anyone know why?

Haydn
  • 293
  • 1
  • 2
  • 13

3 Answers3

1

There seems to be an issue when binding Visuals and VisualBrushes. In this case I would suggest to side step your problem in a way which also fits better MVVM separation. Instead of binding a Visual, create the visual in XAML and bind to the Visual's Source property. Your XAML would be:

<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>

And your code behind:

public Uri MovieUri { get; set; }

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

        InitializeComponent();            
    }
avamir10
  • 21
  • 1
  • Thanks avamir10 for the answer, that method you describe will work, but that won't work for me in the app I am trying to build. In reality I am loading a VisualMedia3D into a Viewport3D dynamically which contains the video. The sample above is just a simplified example. – Haydn Aug 02 '17 at 08:08
0

It seems like this is because your Stuff property does not notify it changed. You have three choices to solve this:

1) Implement the INotifyPropertyChanged interface in your MainWindow class and when setting the Stuff property raise the PropertyChanged event.

2) Define the Stuff property as a DependencyProperty which has inherent property change notifications (since your class is a DependencyObject)

3) Assign the property value before calling InitializeComponent. This will obviously work only once during initialization.

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

    InitializeComponent();
}

These are the two available methods for a property to participate in the Binding game

Clemens
  • 123,504
  • 12
  • 155
  • 268
avamir10
  • 21
  • 1
  • I have tried 1 and 3 and its still not working for some mysterious reason. Will try the second tomorrow. – Haydn Aug 01 '17 at 11:27
  • Tried 2 and checked it was being bound now. It is. Have updated my question. – Haydn Aug 02 '17 at 01:30
0

It's not possible to use a binding to anything that contains a media element and get it to play.

A workaround is you subscribe to the view model property changed event for the object containing the media element. When it changes you add the object programmatically. Then the media element will display and play.

Haydn
  • 293
  • 1
  • 2
  • 13