How can I bind the value cross the window? - wpf

Here is the 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"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<TextBox Text="{Binding CB+Width,RelativeSource={RelativeSource AncestorType={x:Type Window}},Mode=TwoWay}"></TextBox>
</Grid>
</Window>
And here is code-behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
TB = new TextBox();
TB.Width = 200;
}
public ComboBox CB
{
get { return (ComboBox)GetValue(CBProperty); }
set { SetValue(CBProperty, value); }
}
// Using a DependencyProperty as the backing store for CB. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CBProperty =
DependencyProperty.Register("CB", typeof(ComboBox), typeof(MainWindow), null);
}
}
In fact, the DependencyProperty is a custom control, but I replace it as a ComboBox for easy to explain my problem to you.
The custom control is not in the same window and I want to bind its value such as Width to the TextBox.
The custom control is in a different window. That means there are two windows, window 1 and window 2. The custom control is in window 1 and the textbox is in window 2. I do this because one is the main window and the other is the setting window. Whenever the setting window changes the setting, you can see it in the main window at once. So I use a DependencyProperty to store the custom control which in a different window and wanna bind it to the textbox.
Now how can I do it? Would you please help me? Thank you.

It LOOKs like you want your textbox to show the width property of the Window? (or some other control in the future and just testing). If you apply an x:Name value to a control, you can reference that control directly in the XMAL and then properties directly on that. No need for any custom other control with your own dependency property... something like.
<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"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
x:Name="myOuterWindowControl" >
<Grid>
<TextBox Text="{Binding ElementName=myOuterWindowControl, Path=Width, Mode=TwoWay,
UpdateSourceTrigger=LostFocus}" Height="30" Width="70"
HorizontalAlignment="Left" VerticalAlignment="Top"/>
<TextBox Height="30" Width="70"
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,50,0,0"/>
</Grid>
</Window>
Now I actually added an extra textbox control so there is more than one control in the XAML to allow focus to change. Reason. I set the textbox to allow mode as Two-Way binding. The window will push to the textbox, but you can also type in a value to the textbox and when the LOST FOCUS happens, it pushes the value back to the window and you can dynamically change the width (or other property height, coloring, whatever).
Is this more in line with what you were trying to get at?

Related

Integrate VLC player in C# (WPF) project using Vlc.DotNet

I want to integrate to my project a VLC player to display video cameras streams. For that, I try to use Vlc.DotNet (2.1.126 version) in my WPF project.
My tests are done in the following XAML file (I'm a bit a beginner at XAML/WPF):
<UserControl x:Class="TVSCS_View.VideoDisplay.VideoPlayerControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ctrl="clr-namespace:TVSCS_View.VideoDisplay"
xmlns:wpf="clr-namespace:Vlc.DotNet.Wpf;assembly=Vlc.DotNet.Wpf"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300"
x:Name="controlVideoDisplay"
DataContext="{Binding ElementName=controlVideoDisplay}">
<Border BorderBrush="Black"
BorderThickness="1">
<Grid x:Name="videoDisplayLayoutRoot"
Margin="5,5,5,5">
<Image Source="{Binding ElementName=myVlcControl}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
<ctrl:VideoCommandsControl x:Name="videoPlayerControl"
VerticalAlignment="Bottom"
Height="25"
Width="175"
Visibility="Visible"
Margin="10,0,10,20" />
<ctrl:VideoTimeLineControl x:Name="timeLineControl"
VerticalAlignment="Bottom"
Margin="0,0,0,0"/>
</Grid>
</Border>
</UserControl>
And the associated .cs file is:
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Vlc.DotNet.Wpf;
namespace TVSCS_View.VideoDisplay
{
/// <summary>
/// Logique d'interaction pour VideoPlayerControl.xaml
/// </summary>
public partial class VideoPlayerControl : UserControl
{
public VlcControl myVlcControl;
public VideoPlayerControl()
{
InitializeComponent();
MediaPlayer media = new MediaPlayer();
myVlcControl = new VlcControl();
var currentAssembly = Assembly.GetEntryAssembly();
var currentDirectory = new FileInfo(currentAssembly.Location).DirectoryName;
if (Environment.Is64BitOperatingSystem)
{
myVlcControl.MediaPlayer.VlcLibDirectory = new DirectoryInfo(System.IO.Path.Combine(currentDirectory, #"C:\Users\t0115019\Documents\Visual Studio 2015\Projects\tvscs_display\packages\VLC\"));
}
myVlcControl.MediaPlayer.EndInit();
myVlcControl.MediaPlayer.Play(new Uri("C:/Users/Documents/WP_20160908_11_16_53_Pro.mp4"));
}
}
}
Currently, I have an exception "FillNotFOundException" linked to "myVlcControl.MediaPlayer.EndInit()" line when I execute the application.
If I delete this line, nothing is displayed in the UserControl.
Nota:
I try to integrate the VlcControl using the following method:
<UserControl x:Class="TVSCS_View.VideoDisplay.VideoPlayerControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ctrl="clr-namespace:TVSCS_View.VideoDisplay"
xmlns:wpf="clr-namespace:Vlc.DotNet.Wpf;assembly=Vlc.DotNet.Wpf"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300"
x:Name="controlVideoDisplay"
DataContext="{Binding ElementName=controlVideoDisplay}">
<Border BorderBrush="Black"
BorderThickness="1">
<Grid x:Name="videoDisplayLayoutRoot"
Margin="5,5,5,5">
<wpf:VlcControl x:Name="myVlcControl" />
</Grid>
</Border>
</UserControl>
But in this case, i have the following messsage:
the value of type "VlcControl" cannot be added to a collection or dictionary of type 'UIElementCollection'.
Do you have any solution for my little problem?
Thanks
The WPF version of the VlcControl is just a WindowsFormsHost control hosting the Windows Forms version of the VlcControl. Judging by the error message (The value of type "VlcControl" cannot be added to a collection or dictionary of type 'UIElementCollection') you're simply missing a reference to the WindowsFormsIntegration assembly, in which the WindowsFormsHost is defined (it can be found under Assemblies → Framework in the reference manager).
Here's a fully working example of a WPF window hosting the VLC player. You need to install the Vlc.DotNet.Wpf NuGet package (and its dependencies) and reference the WindowsFormsIntegration assembly.
MainWindow.xaml
<Window x:Class="HelloVlc.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vlc="clr-namespace:Vlc.DotNet.Wpf;assembly=Vlc.DotNet.Wpf">
<vlc:VlcControl x:Name="vlcPlayer" />
</Window>
MainWindow.xaml.cs
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
vlcPlayer.MediaPlayer.VlcLibDirectory =
//replace this path with an appropriate one
new DirectoryInfo(#"c:\Program Files (x86)\VideoLAN\VLC\");
vlcPlayer.MediaPlayer.EndInit();
vlcPlayer.MediaPlayer.Play(new Uri("http://download.blender.org/peach/" +
"bigbuckbunny_movies/big_buck_bunny_480p_surround-fix.avi"));
}
}

Navigating to wpf page based on timer

I'm trying to navigate to a different page from my MainWindow in a WPF application. The MainWindow just has some welcome text and I want it to move to another page after 4 seconds. The timer is working just fine but I am getting an error that says,
"Error 1 'UbiTutorial.MainWindow' does not contain a definition for 'Frame' and no extension method 'Frame' accepting a first argument of type 'UbiTutorial.MainWindow' could be found (are you missing a using directive or an assembly reference?) c:\users\thomas\documents\visual studio 2012\Projects\UbiTutorial\UbiTutorial\MainWindow.xaml.cs 54 22 UbiTutorial"
in my method
if (introTime > 4)
{
this.Frame.Navigate(typeof(Touch));
}
Visual Studio is complaining about the Frame part of it.
Frame is a Control Type not a Control Instance, without seeing your Xaml I have no idea of what the name of the Frame that you added is, it probably defaulted to frame1 that is what you will need to use to access the Navigate Method. Hopefully this will give you an idea.
MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Frame Height="100" HorizontalAlignment="Left" Margin="10,10,0,0" Name="frame1" VerticalAlignment="Top" Width="200" />
</Grid>
</Window>
MainWindow.xaml.cs
using System.Windows.Threading;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
DispatcherTimer introTime = new DispatcherTimer();
public MainWindow()
{
InitializeComponent();
introTime.Interval = TimeSpan.FromSeconds(4);
introTime.Tick += new EventHandler(introTime_Tick);
introTime.Start();
}
void introTime_Tick(object sender, EventArgs e)
{
//this.frame1.Navigate(new Uri(#"http://www.google.com"));
this.frame1.Navigate(new UserControl1());
}
}
}
UserControl1.xaml
<UserControl x:Class="WpfApplication1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" Background="Red" >
<Grid>
</Grid>
</UserControl>

How do I get DependencyProperty to work in Silverlight?

I'm trying to bind using a DependencyProperty, but I can't even get the DependencyProperty to work let alone try to bind to it.
I'm following a silverlight guide and up to this point I'm supposed to be able to set the property using XAML. Here is the code I have so far:
MainPage.xaml:
<UserControl
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"
xmlns:local="clr-namespace:UserControlSample" x:Class="UserControlSample.MainPage"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<local:InfoRectangle Margin="32,36,0,0" HorizontalAlignment="Left" Height="70" VerticalAlignment="Top" Width="122" InfoText="New Text"/>
<local:InfoRectangle Margin="105,139,188,97" InfoText="some text" />
</Grid>
InfoRectangle.xaml:
<UserControl
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"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
mc:Ignorable="d"
x:Class="UserControlSample.InfoRectangle"
d:DesignWidth="122" d:DesignHeight="70">
<Grid x:Name="LayoutRoot">
<Rectangle Fill="#FFABABE9" Stroke="Black" RadiusY="4" RadiusX="4"/>
<TextBlock Name="InfoLabel" Text="Text block" Margin="5" />
</Grid>
InfoRectangle.xaml.cs:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace UserControlSample
{
public partial class InfoRectangle : UserControl
{
public InfoRectangle()
{
// Required to initialize variables
InitializeComponent();
}
public string InfoText
{
get { return (string)GetValue(InfoTextProperty); }
set { SetValue(InfoTextProperty, value); }
}
public static readonly DependencyProperty InfoTextProperty =
DependencyProperty.Register(
"InfoText",
typeof(string),
typeof(InfoRectangle),
new PropertyMetadata("something", InfoTextChanged));
private static void InfoTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
}
}
}
When I run the solution the two rectangles show up but they display just "Text block" which is neither the default set or the value set in the MainPage XAML for the user controls.
My answer in here details a nice compact example of a dependency property updating a given property on a view model. The property on your view model would be bound to your text block so once change notification fires, your text block should update.
Here is the solution;
It seems the callback method has to be completed.
private static void InfoTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((InfoRectangle)d).InfoLabel.Text = e.NewValue.ToString();
}

Custom ItemControl for ListBox

I want to add new DependencyProperty to ListBoxItem class which used in ListBox control. I need to add IsEditing property. When user will does long click on my ListBoxItem I will change it IsEditing property to True and then in Trigger of this property will be style changing. Actually the idea to change TextBlock to TextBox in style.
I hope my explanation is clear. Does it make any sense, or there is exist more simple way?
Thanks
See the XAML below - A child of DataTemplate is your item's template. You can use built-in WPF elements like Grid, Canvas etc. or your own user/custom control. You can create EditableItem control and use it to handle long mouse clicks etc.
This is not the most elegant way of doing this, but probably the simplest one. The more advanced approach would involve the usage of attached behaviors, which elliminates need for custom/user controls. Also, look at VisualStateManager class, it'll simplify switching between different 'modes' of your editable item (that's what I'd use for it anyway).
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ListBox x:Name="l">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="30" Background="Green" Width="100">
<TextBlock Text="{Binding}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Loaded += (o, e) =>
{
this.l.ItemsSource = Enumerable.Range(1, 3);
};
}
}
}

Does VS2010 show data in UserControls during design time?

I have a trivial user control:
<UserControl x:Class="Xxx.SimpleUserControl.SimpleTextUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="root">
<StackPanel Background="Blue">
<TextBlock x:Name="TitleTextBlock" Text="{Binding ElementName=root, Path=Title}" Background="White" Width="200" Height="30" Margin="5" />
<TextBlock Text="{Binding ElementName=root, Path=Time}" Background="White" Width="200" Height="30" Margin="9" />
</StackPanel>
</UserControl>
and the code behind:
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
namespace Xxx.SimpleUserControl
{
/// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
public partial class SimpleTextUserControl : UserControl
{
public SimpleTextUserControl()
{
InitializeComponent();
}
[Browsable(true)]
[Category("SimpleControl")]
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
// Using a DependencyProperty as the backing store for Title. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(SimpleTextUserControl), new FrameworkPropertyMetadata("hello"));
[Browsable(true)]
[Category("SimpleControl")]
public DateTime Time
{
get { return (DateTime)GetValue(TimeProperty); }
set { SetValue(TimeProperty, value); }
}
// Using a DependencyProperty as the backing store for Time. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TimeProperty =
DependencyProperty.Register("Time", typeof(DateTime), typeof(SimpleTextUserControl), new UIPropertyMetadata(DateTime.Now));
}
}
I naively expect the VS2010 designer for the UserControl to display my default metadata values for my two controls - "hello" in one textblock, and today's date and time in other, but they are empty.
If I compile, and drop the control in to a WPF application, it renders fine, but not whilst in the UserControl project xaml view/designer.
I've tried changing the datacontext around, binding in different ways, implementing OnPropertyChanged etc., but nothing makes the data render in the UserControl project's design view.
Does anyone know the answer to this one? I've searched around, and either it's so obvious I'm missing it, or it's 'just the way it is'.
I think you'll need to use a "DesignTime" DataContext. Add the following to your UserControl Xaml file
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:YourNamespace"
mc:Ignorable="d"
And then set the DesignTime DataContext with
d:DataContext="{d:DesignInstance local:SimpleTextUserControl,
IsDesignTimeCreatable=True}"
And remove ElementName from the Bindings
<UserControl x:Class="YourNamespace.SimpleTextUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:YourNamespace"
mc:Ignorable="d"
x:Name="root"
d:DataContext="{d:DesignInstance local:SimpleTextUserControl,
IsDesignTimeCreatable=True}">
<StackPanel Background="Blue">
<TextBlock x:Name="TitleTextBlock" Text="{Binding Path=Title}" Background="White" Width="200" Height="30" Margin="5" />
<TextBlock Text="{Binding Path=Time}" Background="White" Width="200" Height="30" Margin="9" />
</StackPanel>
</UserControl>
If you're still having problems getting this to work I uploaded a small sample project which you can compare to: http://www.mediafire.com/?gan28oeel4qf7ik

Resources