Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Data Binding in WPF User Controls

I am creating a UserControl for a series of controls shared by several windows. One of the controls is a Label which shows the flow of some other process in terms of "protocol numbers".

I am trying to offer DataBinding with this Label so the Window automatically reflects the state of the process as the protocol number variable changes.

This is the User control XAML:

<UserControl Name="MainOptionsPanel"     x:Class="ExperienceMainControls.MainControls"     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     DataContext="{Binding RelativeSource={RelativeSource Self}}"     > <Label Height="Auto" Name="numberLabel">Protocol:</Label> <Label Content="{Binding Path=ProtocolNumber}" Name="protocolNumberLabel"/> (...) </UserControl> 

And this is the Code-Behind:

public partial class MainControls  {     public MainControls()     {         InitializeComponent();     }      public int ProtocolNumber     {         get { return (int)GetValue(ProtocolNumberProperty); }         set { SetValue(ProtocolNumberProperty, value); }     }      public static DependencyProperty ProtocolNumberProperty =         DependencyProperty.Register("ProtocolNumber", typeof(int), typeof(MainControls)); } 

This seems to be working because if on the constructor I set ProtocolNumber to an arbitrary value, it is reflected in the user control.

However, when using this usercontrol on the final window, the data binding breaks.

XAML:

<Window x:Class="UserControlTesting.Window1"     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:expControl="clr-namespace:ExperienceMainControls;assembly=ExperienceMainControls"     DataContext="{Binding RelativeSource={RelativeSource Self}}"     >     <StackPanel>         <expControl:MainControls ProtocolNumber="{Binding Path=Number, Mode=TwoWay}" />     </StackPanel>  </Window> 

Code-Behind for window:

public partial class Window1 : Window {     public Window1()     {         Number= 15;         InitializeComponent();     }      public int Number { get; set; } } 

This sets the Protocol Number to zero, ignoring the value set to Number.

I've read example

like image 525
Gabriel Sanmartin Avatar asked Jun 27 '12 13:06

Gabriel Sanmartin


People also ask

How does data binding work in WPF?

Data binding is a mechanism in WPF applications that provides a simple and easy way for Windows Runtime apps to display and interact with data. In this mechanism, the management of data is entirely separated from the way data. Data binding allows the flow of data between UI elements and data object on user interface.

Which class is used for data binding in WPF?

WPF data binding supports data in the form of CLR objects and XML. To provide some examples, your binding source may be a UIElement, any list object, a CLR object that is associated with ADO.NET data or Web Services, or an XmlNode that contains your XML data.

How data binding happens explain with an example?

Data binding can also mean that if an outer representation of the data in an element changes, then the underlying data can be automatically updated to reflect the change. For example, if the user edits the value in a TextBox element, the underlying data value is automatically updated to reflect that change.


1 Answers

if you look at your output window you should see the binding exception.

The problem you have is the following: within your usercontrol you will bind the label to the DP ProtocolNumber of your usercontrol and not the DataContext, so you have to add for example the element name to the binding.

<UserControl Name="MainOptionsPanel"     x:Class="ExperienceMainControls.MainControls"     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     x:Name="uc"     > <Label Height="Auto" Name="numberLabel">Protocol:</Label> <Label Content="{Binding Path=ProtocolNumber, ElementName=uc}" Name="protocolNumberLabel"/> (...) </UserControl> 

EDIT: to clear some things up, your usercontrol also works if you change the binding in your MainWindow. but you have to bind to the DataContext of the MainWindow with RelativeSource.

    <expControl:MainControls ProtocolNumber="{Binding Path=Number, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" /> 
like image 121
blindmeis Avatar answered Sep 20 '22 15:09

blindmeis