Data Binding in WPF User Controls
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}}}" />
Data binding to a UserControl in WPF
You set the DataContext in the Control to itself, thus overwriting the DataContext when using this Control in other controls. Taking your binding as example in your situation:
<src:BlueTextBox BlueText="{Binding Path=MyString}" />
Once loaded and all the Datacontext is set, it will look for the path MyString in your BlueTextBox thing control due to you setting the DataContext to it. I guess this is not how you intended this to work ;).
Solution:
Change the text binding either one of the 2 bindings:
{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:BlueTextBox}}, Path=BlueText}
or
Name your control Root (or something like that)
<UserControl x:Name="Root"
{Binding ElementName=Root, Path=BlueText}
And remove the
DataContext = this;
from the constructor of your UserControl and it should work like a charm..
How to set DataBinding for UserControl with ViewModel
A UserControl that is supposed to operate on a particular view model class - or more precisely on a class with a particular set of public properties - may directly bind to the view model properties in its XAML.
Given a view model like
public class Model
{
public string Something { get; set; }
}
you may write a UserControl with nothing more than this XAML
<UserControl ...>
...
<TextBox Text="{Binding Something}" />
...
</UserControl>
and this code behind
public partial class Wizard : UserControl
{
public Wizard()
{
InitializeComponent();
}
}
If you now set its DataContext to an instance of Model
(or any other class with a Something
property), it will just work:
<local:Wizard DataContext="{Binding MyModel}"/>
Since the value of the DataContext property is inherited from parent to child elements, this will also work:
<StackPanel DataContext="{Binding MyModel}">
<local:Wizard/>
</StackPanel>
However, the UserControl still dependends on the existence of a Something
property in its DataContext. In order to get rid of this dependence, your control may expose a dependency property
public static readonly DependencyProperty MyTextProperty =
DependencyProperty.Register(nameof(MyText), typeof(string), typeof(Wizard));
public string MyText
{
get { return (string)GetValue(MyTextProperty); }
set { SetValue(MyTextProperty, value); }
}
and bind the element in its XAML to its own property
<UserControl ...>
...
<TextBox Text="{Binding MyText,
RelativeSource={RelativeSource AncestorType=UserControl}}"/>
...
</UserControl>
Now you would bind the control's property instead of setting its DataContext:
<local:Wizard MyText="{Binding MyModel.Something, Mode=TwoWay}"/>
WPF User Control Binding
This markup requires you to add a dependency property called File
to the ControlUploadDataItem
control:
<controls:ControlUploadDataItem File="{Binding}" />
You should also avoid setting the DataContext
property in the constructor of the control as this will prevent it from inherting the DataContext
from the parent element in the object tree:
this.DataContext = new UploadDataViewModel();
You don't really need an UploadDataViewModel
here. The File
property belongs to the control and is bound to the FileInfo
in the source collection of the ListView
in the ItemTemplate
of the same. The ControlUploadDataItem
control can then bind properties of its own File
dependency property.
WPF Cross User Control Data Binding
EmployeeRecordControl seems redundant. Instead of that, just use a DataGrid directly, and bind its ItemsSource
and SelectedItem
to two properties of a view model class like this:
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<Employee> Employees { get; }
= new ObservableCollection<Employee>();
private Employee selectedEmployee;
public Employee SelectedEmployee
{
get => selectedEmployee;
set
{
selectedEmployee = value;
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(nameof(SelectedEmployee)));
}
}
}
Then create and bind to the view model like this:
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<DataGrid ItemsSource="{Binding Employees}"
SelectedItem="{Binding SelectedEmployee}"
CanUserAddRows="False"/>
<local:EmployeeDetailControl Grid.Column="1"
DataContext="{Binding SelectedEmployee}"/>
</Grid>
wpf, binding data to child of another usercontrol
In your User control, you should add a get accessor like this:
public int ListCount {
get {
return this.lbDemo.Items.Count;
}
}
And in your Main Window, you call it like this:
<TextBlock Text="{Binding ElementName=userControlDemo, Path=ListCount, StringFormat='there are {0} items in the listbox of Usercontrol1'}" />
Custom user control in WPF with data binding
When you do
<UserControl ... DataContext="{Binding RelativeSource={RelativeSource Self}}">
you effectively overwrite DataContext
that would normally be passed to your control from visual tree and you change binding context for bindings within NameControl
control. I would suggest to remove that and do that per binding
<TextBlock ... Text="{Binding FirstName, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
<TextBlock ... Text="{Binding LastName, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
or to make it simpler give UserControl
some name and use it for bindings within your control
<UserControl... x:Name="myUserControl">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Width="100" Text="{Binding FirstName, ElementName=myUserControl}" />
<TextBlock Grid.Column="1" Width="100" Text="{Binding LastName, ElementName=myUserControl}" />
</Grid>
</UserControl>
DataBinding to a UserControl inside of a UserControl
This can all be greatly simplified.
First, get rid of every Canvas
in your UserControl
s. Canvas isn't just a neutral panel/container control. The Canvas
es will cause everything to be superimposed. Only use a Canvas
when you want to position children arbitrarily, and potentially superimposed. WPF layout usually uses "flow" and relative positioning. The standard layout parents are StackPanel
, Grid
, WrapPanel
, and the occasional UniformGrid
. You can omit the ItemsPanelTemplate
for the ItemsControl
, since the default is already a vertically-oriented StackPanel
.
How to databind property from view model to custom user control in WPF?
I managed to solve it by setting my control DataContext to grid like MyGrid.DataContext = new BindingControlViewModel();
instead of setting it on the control itself like this.DataContext = new BindingControlViewModel();
.
Related Topics
Upload File Through C# Using JSON Request and Restsharp
Unity: Apple Game Center iOS7 Registers the Scores for Only 30 Minutes in the Leaderboard
How to Call Code Behind Server Method from a Client Side JavaScript Function
JavaScript Date to C# via Ajax
How to Call an ASP.NET C# Method Using JavaScript
Asp.Net-Mvc: Razor '@' Symbol in Js File
How to Convert JavaScript Datetime to C# Datetime
How to Return JSON with ASP.NET & Jquery
How to Convert JavaScript Date Object to Ticks
How to Load a C# Dll in Python
Python: Inflate and Deflate Implementations
C# Version of Java's Synchronized Keyword
Why C# Implements Methods as Non-Virtual by Default
How to Find a Java to C# Converter