Binding Dependency Property to View Model - wpf

I have two user controls defined as follows:
User Control 1
XAML
<UserControl x:Class="TestBindings.UserControlOne"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestBindings">
<UserControl.DataContext>
<local:UserControlOneViewModel/>
</UserControl.DataContext>
<StackPanel>
<TextBlock Text="{Binding MyProperty}"/>
<local:UserControlTwo PropertyTwo="{Binding DataContext.MyProperty, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"/>
</StackPanel>
</UserControl>
Code Behind
public partial class UserControlOne : UserControl
{
public UserControlOne()
{
InitializeComponent();
}
}
User Control 2
XAML
<UserControl x:Class="TestBindings.UserControlTwo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestBindings">
<UserControl.DataContext>
<local:UserControlTwoViewModel/>
</UserControl.DataContext>
<TextBlock Name="TextBlock" Text="{Binding PropertyTwo}"/>
</UserControl>
Code Behind
public partial class UserControlTwo : UserControl
{
public static readonly DependencyProperty PropertyTwoProperty =
DependencyProperty.Register("PropertyTwo", typeof (string), typeof (UserControlTwo),
new FrameworkPropertyMetadata("Default", OnPropertyTwoChanged));
public UserControlTwo()
{
InitializeComponent();
var propertyTwoBinding = new Binding("PropertyTwo") {Mode = BindingMode.TwoWay};
SetBinding(PropertyTwoProperty, propertyTwoBinding);
}
public string PropertyTwo
{
get { return (string) GetValue(PropertyTwoProperty); }
set { SetValue(PropertyTwoProperty, value); }
}
private static void OnPropertyTwoChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var userControlTwo = (UserControlTwo) d;
userControlTwo.PropertyTwo = (string) e.NewValue;
}
}
In UserControlTwo's constructor I bind the dependency property PropertyTwoProperty to a property in the associated ViewModel. I ultimately want to bind this to a property in the ViewModel of UserControlOne, hence UserControlOne xaml
<local:UserControlTwo PropertyTwo="{Binding DataContext.MyProperty, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"/>
However this never seems to get set. Any ideas where I may be going wrong?

I think you are trying to pass a property from the datacontext of UserControlOne to a DependencyProperty in UserControlTwo.
In that case you use the below approach and also remove the setbinding in the code in your UserControl2 Constructor. Let me know if this is what you are looking for.
<UserControl x:Class="TestBindings.UserControlOne"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="userControl"
xmlns:local="clr-namespace:TestBindings">
<UserControl.DataContext>
<local:UserControlOneViewModel/>
</UserControl.DataContext>
<StackPanel>
<TextBlock Text="{Binding MyProperty}"/>
<local:UserControlTwo PropertyTwo="{Binding DataContext.MyProperty, ElementName=userControl,Mode=TwoWay}"/>
</StackPanel>
</UserControl>

Related

wpf UserControl command button click binding

I have usercontrol:
<UserControl x:Class="MyApp.Header"
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="40" d:DesignWidth="300" DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}}">
<Grid>
<Label Content="{Binding LableContent, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"></Label>
<Button Command="{Binding Path=AddClick, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}">
<Image Source="{StaticResource addImage}" Height="20"/>
</Button>
</Grid>
</UserControl>
And dependency property in usercontoror:
public string LableContent
{
get { return (string)GetValue(LableContentProperty); }
set { SetValue(LableContentProperty, value); }
}
public static readonly DependencyProperty LableContentProperty =
DependencyProperty.Register("LableContent", typeof(string), typeof(Header));
public ICommand AddClick
{
get { return (ICommand)GetValue(AddClickProperty); }
set { SetValue(AddClickProperty, value); }
}
public static readonly DependencyProperty AddClickProperty =
DependencyProperty.Register("AddClick", typeof(ICommand), typeof(Header));
I added usercontrol on mainwindow:
<local:Header AddClick="{Binding Path=AddUser_Click}" LableContent="Users"></local:Header>
And add click event on MainWindow.cs
private void AddUser_Click(object sender, RoutedEventArgs e)
{
}
The problem is that the Lable is being filled, but the command click the button is not called. What am I doing wrong?
There are two things you need to set
Specify the DataContext for window.xaml and relative source for the AddClick command so that AddUser_Click can be found on Window.
Update your Window.xaml AddClick binding to
<local:Header AddClick="{Binding Path=DataContext.AddUser_Click, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}" LableContent="Users"/>
and set DataContext of Window.xaml to Window.xaml.cs by adding this to your MainWindow constructor
this.DataContext = this;
Doing the above step will ensure that the AddUser_Click property can be found correctly.
All dependency properties when binded tries to find a property in the DataContext and not method. So, the command should be a property on window.cs of type ICommand and it should be given a method in the constructor.
To implement this most people use http://www.wpftutorial.net/delegatecommand.html. Simply copy this to a new file.
In your MainWindow.xaml.cs, add this
AddUser_Click = new DelegateCommand(AddUserMethod);
You can now add a method named AddUserMethod in the same file and it will be called whenever you click the button from the User Control!!

Closing-EventTrigger on a WPF Window - Problems with DataContext

I have a view, which initializes a viewmodel inside the windows resources. Further more I give my grid the DataContext.
My question is, how I can add a command to my windows closing event keeping mvvm in memory? I tried the version of this post:
Handling the window closing event with WPF / MVVM Light Toolkit
... but its not working using an event-trigger, because I can't access the viewmodel from outside my grid, so I can't access my command.
Any solution for my problem?
Greetings
Jannik
Edit: Here's my xaml:
<Window x:Class="WpfApplication1.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModels="clr-namespace:WpfApplication1.ViewModels"
xmlns:converter="clr-namespace:WpfApplication1.Converter"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<viewModels:MainWindowViewModel x:Key="ViewModel"/>
</Window.Resources>
<Grid DataContext="{StaticResource ViewModel}">...</Grid>
</Window>
You can reference to members of a static resource this way:
Command="{Binding Path=CloseCommand, Source={StaticResource ViewModel}}"
Here's the complete test project. I used a text box with a binding to ensure data is saved.
<Window x:Class="WpfApplication1.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModels="clr-namespace:WpfApplication1.ViewModels"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<viewModels:MainWindowViewModel x:Key="ViewModel"/>
</Window.Resources>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Closing">
<i:InvokeCommandAction Command="{Binding Path=CloseCommand, Source={StaticResource ViewModel}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid DataContext="{StaticResource ViewModel}">
<TextBox Text="{Binding Txt, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</Window>
In ViewModel code, I used a static reference to store data (LastInstance). you can replace it with your own method.
Also I used Command which is a custom implementation of ICommand. If you want I can add the complete implementation here.
public MainWindowViewModel()
{
//save or load here...
if (LastInstance != null) Txt = LastInstance.Txt;
CloseCommand = new Command(o => LastInstance = this);
//...
}
public static ViewModel LastInstance;
//Txt Dependency Property
public string Txt
{
get { return (string)GetValue(TxtProperty); }
set { SetValue(TxtProperty, value); }
}
public static readonly DependencyProperty TxtProperty =
DependencyProperty.Register("Txt", typeof(string), typeof(ViewModel), new UIPropertyMetadata(null));
//CloseCommand Dependency Property
public Command CloseCommand
{
get { return (Command)GetValue(CloseCommandProperty); }
set { SetValue(CloseCommandProperty, value); }
}
public static readonly DependencyProperty CloseCommandProperty =
DependencyProperty.Register("CloseCommand", typeof(Command), typeof(ViewModel), new UIPropertyMetadata(null));
The typical approach to this problem is to have a MainViewModel and set the DataContext of you Window to it. Then define other viewModels in the MainViewModel.
<Window>
<Grid DataContext="{Binding MyGridViewModel}">
</Grid>
<DockPanel DataContext="{Binding AnotherViewModel}">
</DockPanel>
</Window>
in MainWindow constructor:
this.DataContext = new MainViewModel();
in MainViewModel constructor:
this.MyGridViewModel = new OtherViewModel();
This way you have many options to find the desired object through viewModel references.

Using MVVM Light EventToCommand In DataTemplate

So I have a WPF UserControl:
<UserControl x:Class="BI_Builder.Views.ObjectTreeView"
x:Name="UC1"
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:BI_Builder"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:viewModels="clr-namespace:BI_Builder.ViewModels"
xmlns:command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" DataContext="{Binding}">
<UserControl.Resources>
<ContentControl x:Key="Context" Content="{Binding}" />
<DataTemplate x:Key="DataSourceTemplate">
<TextBlock Text="{Binding Path=Name}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<command:EventToCommand Command="{Binding Path=DataContext.OpenCommand, Mode=OneWay,ElementName=UC1}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
</DataTemplate>
<HierarchicalDataTemplate x:Key="ItemTemplate"
ItemsSource="{Binding Children}"
ItemTemplate="{StaticResource DataSourceTemplate}">
<StackPanel>
<TextBlock Text="{Binding Header}">
</TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
</UserControl.Resources>
<Grid>
<TreeView Name="TreeView" ItemsSource="{Binding Items}" ItemTemplate="{StaticResource ItemTemplate}" >
</TreeView>
</Grid>
</UserControl>
And here's the main view model for the user control:
public class ObjectTreeViewModel : ObservableObject {
public ObservableCollection<ItemViewModel> Items {
get {
if (_items != null) return _items;
_items = new ObservableCollection<ItemViewModel>();
_items.Add(DataSources);
return _items;
}
set { _items = value;
}
}
public ItemViewModel DataSources {
get { return _dataSources ?? (_dataSources = new ItemViewModel() { Header = "Data Sources", Children = new ObservableCollection<object>(DataSourceList) }); }
set { _dataSources = value; }
}
public List<DataSource> DataSourceList;
public ICommand OpenCommand {
get { if (_openCommand == null) { return _openCommand = new RelayCommand(OpenDataSource); } return _openCommand; }
}
private void OpenDataSource() {
MessageBox.Show("Test");
}
public ObjectTreeViewModel() {
DataSourceList = new List<DataSource>();
DataSourceList.Add(new DataSource() { Name = "Test" });
}
private ItemViewModel _dataSources;
private ObservableCollection<ItemViewModel> _items;
private RelayCommand _openCommand;
}
}
I've tried every method I've come across on the web to get the EventToCommand in the DataSourceTemplate DataTemplate to fire. In fact, I'm pretty sure it knows where the OpenCommand is, because if I change the Path to gobbledygook, the Output window throws me an error saying that "ObjectTreeView" (which is the instance of the ObjectTreeViewModel view model being bound to the UserControl) doesn't have the gobbledygook property. So I think I've set the DataContext correctly ...
But whenever I click on the text blocks ... nothing.
Really trying to avoid code-behind (it just feels wrong), and full disclosure, I'm using MVVM Light's EventToCommand but not the full toolkit, although I'm tempted to rewrite what I have so far in it to see if using the Service Locator will solve this problem.
The TextBlock control does not have a Click event. See MSDN.
You should use the MouseLeftButtonDown event instead:
<i:EventTrigger EventName="MouseLeftButtonDown">
<!-- ... -->
</i:EventTrigger>
Can you put a hyperlink inside your textblock instead and bind the command to the hyperlink?
Note you can style the hyperlink to look like a plain textblock if needed.
<TextBlock>
<Hyperlink Command="{Binding Path=DataContext.OpenCommand" Text="{Binding Path=Name}" />
</TextBlock>
Also make sure that the ObjectTreeView class is instantiated and loaded into DataContext of the usercontrol.

Silverlight: How to bind to parent view's DataContext?

I have a ParentView that contains a childView
<UserControl ... x:Name="MyParentView">
<Grid>
<sdk:TabControl Name="ContactTabControl">
<sdk:TabItem Header="Contact" Name="CustomerTabItem">
<Grid>
<Views:CustomerView/>
</Grid>
</sdk:TabItem>
</sdk:TabControl>
</Grid>
</UserControl>
Within my CustomerView I would like to bind the Firstname textbox to Parent's DataContext. I have tried this inside the CustomerView:
<TextBox Text={Binding ElementName=MyParentView, Path=DataContext.Firstname} />
I have the feeling that CustomerView won't be able to see its parent at all, hence the ElementName "MyParentView" would never be found.
What is your advice on this?
I've done a similar thing but I just bound it directly to Path considering that if I don't give it explicit data context, it will lookup the hierarchy and find one that matches.
So this should get you what you want:
<TextBox Text={Binding Path=FirstName} />
if you need to specify explicit datacontext you can always do:
<Grid>
<Views:CustomerView DataContext={"CustomContextHere"}/>
</Grid>
An alternative solution to Maverik's is :
1 Define a dependency property in your customer view :
public partial class CustomerView : UserControl
{
public CustomerView()
{
InitializeComponent();
}
public static DependencyProperty FirstNameProperty =
DependencyProperty.Register("FirstName", typeof(string), typeof(CustomerView), new PropertyMetadata(string.Empty, CustomerView.FirstNameChanged));
public string FirstName
{
get { return (string)GetValue(FirstNameProperty); }
set { SetValue(FirstNameProperty, value); }
}
private static void FirstNameChanged(object sender, DependencyPropertyChangedEventArgs e)
{ }
}
2 Modify the customer view's textbox to bind to this dependency property (note the element binding "this")
<UserControl x:Class="SLApp.CustomerView"
x:Name="this"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<TextBox Text="{Binding Path=FirstName, ElementName=this, Mode=TwoWay}"/>
</Grid> </UserControl>
3 Modify the parent view and bind it's DataContext to the new dependency property
<sdk:TabControl Name="ContactTabControl">
<sdk:TabItem Header="Contact" Name="CustomerTabItem">
<Grid>
<local:CustomerView FirstName="{Binding ElementName=ContactTabControl, Path=DataContext}"/>
</Grid>
</sdk:TabItem>
</sdk:TabControl>
4 Set the parent's DataContext
public partial class MyParentView : UserControl
{
public MyParentView()
{
InitializeComponent();
ContactTabControl.DataContext = "A name";
}
}
Voila' it works. Not the most elegant solution but it gets the job done for your scenario

Silverlight UserControl Custom Property Binding

What is the proper way to implement Custom Properties in Silverlight UserControls?
Every "Page" in Silverlight is technically a UserControl (they are derived from the UserControl class). When I say UserControl here, I mean a Custom UserControl that will be used inside many different pages in many different scenarios (similar to an ASP.NET UserControl).
I would like the Custom UserControl to support Binding and not rely on the Name of the Property it is binding to, to always be the same. Instead, I would like the UserControl itself to have a property that the Controls inside the UserControl bind to, and the ViewModels outside the UserControl also bind to. (please see the example below)
Binding within the UserControl works, Binding within the MainPage works, The Binding I set up between the MainPage and the UserControl does not work. Specifically this line:
<myUserControls:MyCustomUserControl x:Name="MyCustomControl2"
SelectedText="{Binding MainPageSelectedText, Mode=TwoWay}"
Width="200" Height="50" />
example output:
MainPage.xaml
<UserControl x:Class="SilverlightCustomUserControl.MainPage"
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:myUserControls="clr-namespace:SilverlightCustomUserControl"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Canvas x:Name="LayoutRoot">
<StackPanel Orientation="Vertical">
<TextBlock Text="UserControl Binding:" Width="200"></TextBlock>
<myUserControls:MyCustomUserControl x:Name="MyCustomControl2" SelectedText="{Binding MainPageSelectedText, Mode=TwoWay}" Width="200" Height="50" />
<TextBlock Text="MainPage Binding:" Width="200"></TextBlock>
<TextBox Text="{Binding MainPageSelectedText, Mode=TwoWay}" Width="200"></TextBox>
<Border BorderBrush="Black" BorderThickness="1">
<TextBlock Text="{Binding MainPageSelectedText}" Width="200" Height="24"></TextBlock>
</Border>
</StackPanel>
</Canvas>
</UserControl>
MainPage.xaml.cs
namespace SilverlightCustomUserControl
{
public partial class MainPage : UserControl, INotifyPropertyChanged
{
//NOTE: would probably be in a ViewModel
public string MainPageSelectedText
{
get { return _MainPageSelectedText; }
set
{
string myValue = value ?? String.Empty;
if (_MainPageSelectedText != myValue)
{
_MainPageSelectedText = value;
OnPropertyChanged("MainPageSelectedText");
}
}
}
private string _MainPageSelectedText;
public MainPage()
{
InitializeComponent();
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string name)
{
PropertyChangedEventHandler ph = this.PropertyChanged;
if (ph != null)
ph(this, new PropertyChangedEventArgs(name));
}
#endregion
}
}
MyCustomUserControl.xaml
<UserControl
x:Class="SilverlightCustomUserControl.MyCustomUserControl"
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"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<StackPanel>
<TextBox Text="{Binding SelectedText, Mode=TwoWay}" />
<Border BorderBrush="Black" BorderThickness="1">
<TextBlock Text="{Binding SelectedText}" Height="24"></TextBlock>
</Border>
</StackPanel>
</Grid>
</UserControl>
MyCustomUserControl.xaml.cs
namespace SilverlightCustomUserControl
{
public partial class MyCustomUserControl : UserControl
{
public string SelectedText
{
get { return (string)GetValue(SelectedTextProperty); }
set { SetValue(SelectedTextProperty, value); }
}
public static readonly DependencyProperty SelectedTextProperty =
DependencyProperty.Register("SelectedText", typeof(string), typeof(MyCustomUserControl), new PropertyMetadata("", SelectedText_PropertyChangedCallback));
public MyCustomUserControl()
{
InitializeComponent();
}
private static void SelectedText_PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//empty
}
}
}
References (how I got this far):
use DependencyPropertys:
http://geekswithblogs.net/thibbard/archive/2008/04/22/wpf-custom-control-dependency-property-gotcha.aspx
use DependencyPropertys, add x:Name to your UserControl - add Binding with ElementName, set Custom property again in the PropertyChangedCallback method:
Setting Custom Properties in UserControl via DataBinding
don't use custom properties, rely on underlying datacontext names (I do not like this solution):
wpf trouble using dependency properties in a UserControl
I understand it as the reason your control is not receiving the new value from the maim page is that you are setting the DataContext of the control. If you hadn't then the control's DataContext will be inherited from its parent, the main page in this case.
To get this to work I removed you control's DataContext setting, added an x:Name to each control and set the binding in the constructor of the control using the [name].SetBinding method.
I did the binding in the ctor as I couldn't figure out a way of setting the Source property of the declarative binding in the xaml to Self. i.e. {Binding SelectedText, Mode=TwoWay, Source=[Self here some how]}. I did try using RelativeSource={RelativeSource Self} with no joy.
NOTE: All this is SL3.
The Issue was the UserControl was throwing a DataBinding error (visible in the Output window while debugging)
Because The UserControl's DataContext was set to "Self" in its own xaml, it was looking for the MainPageSelectedText within its own context (it was not looking for the MainPageSelectedText within the "MainPage" which is where you might think it would look, because when you are physically writing/looking at the code that is what is in "context")
I was able to get this "working" by setting the Binding in the code behind. Setting the binding in the code behind is the only way to set the UserControl itself as the "Source" of the binding. But this only works if the Binding is TwoWay. OneWay binding will break this code. A better solution altogether would be to create a Silverlight Control, not a UserControl.
See Also:
http://social.msdn.microsoft.com/Forums/en-US/silverlightcontrols/thread/052a2b67-20fc-4f6a-84db-07c85ceb3303
http://msdn.microsoft.com/en-us/library/cc278064%28VS.95%29.aspx
MyCustomUserControl.xaml
<UserControl
x:Class="SilverlightCustomUserControl.MyCustomUserControl"
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">
<Grid>
<StackPanel>
<TextBox x:Name="UserControlTextBox" />
<Border BorderBrush="Black" BorderThickness="1">
<TextBlock x:Name="UserControlTextBlock" Height="24"></TextBlock>
</Border>
</StackPanel>
</Grid>
</UserControl>
MyCustomUserControl.xaml.cs
namespace SilverlightCustomUserControl
{
public partial class MyCustomUserControl : UserControl
{
public string SelectedText
{
get { return (string)GetValue(SelectedTextProperty); }
set { SetValue(SelectedTextProperty, value); }
}
public static readonly DependencyProperty SelectedTextProperty =
DependencyProperty.Register("SelectedText", typeof(string), typeof(MyCustomUserControl), new PropertyMetadata("", SelectedText_PropertyChangedCallback));
public MyCustomUserControl()
{
InitializeComponent();
//SEE HERE
UserControlTextBox.SetBinding(TextBox.TextProperty, new Binding() { Source = this, Path = new PropertyPath("SelectedText"), Mode = BindingMode.TwoWay });
UserControlTextBlock.SetBinding(TextBlock.TextProperty, new Binding() { Source = this, Path = new PropertyPath("SelectedText") });
//SEE HERE
}
private static void SelectedText_PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//empty
}
}
}
Instead of binding data context to self, you can set the binding in xaml by adding an x:Name for the user control and then binding in the user control xaml follows:
<UserControl
x:Class="SilverlightCustomUserControl.MyCustomUserControl"
x:Name="myUserControl
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">
<Grid>
<StackPanel>
<TextBox Text="{Binding SelectedText, ElementName=myUserContol, Mode=TwoWay}" />
<Border BorderBrush="Black" BorderThickness="1">
<TextBlock Text="{Binding SelectedText,ElementName=myUserControl}" Height="24"></TextBlock>
</Border>
</StackPanel>
</Grid>
</UserControl>

Resources