TextBox in UserControl does not display anything [duplicate] - c#

This question already has an answer here:
XAML binding not working on dependency property?
(1 answer)
Closed 2 years ago.
I would like to display my score point in a textbox, even if the textbox.Text get the value, in GUI i can't see my score.
<UserControl x:Class="WpfCyberPunk.UserControls.UserControlPlaying"
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:WpfCyberPunk.UserControls"
mc:Ignorable="d"
d:DesignHeight="350" Width="Auto" d:DataContext="{d:DesignData }">
<Grid Name="PlayingGrid" Margin="0,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Row="0" HorizontalAlignment="Left">
<StackPanel Name="SkPn_Score" Orientation="Horizontal">
<TextBlock HorizontalAlignment="Left" Margin="10,1,0,0" TextWrapping="Wrap" Text="Point de départ" VerticalAlignment="Center" Height="25" Width="100"/>
<TextBox x:Name = "tBx_StartPt" Text="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=ScoreText,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged }" TextChanged="TBx_StartPt_OnTextChanged" FontSize="10" HorizontalAlignment="Left" Margin="10,1,0,0" TextWrapping="Wrap" VerticalAlignment="Center" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Height="25" Width="50"/>
</StackPanel>
</Grid>
IN cs, I have
public partial class UserControlPlaying : UserControl
{
private string _score;
private int _point;
//public event DependencyProperty PropertyChanged;
public string Score
{
get => _score;
set
{
_score = value;
SetValue(ValueProperty, _score);
}
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Score", typeof(string), ownerType: typeof(UserControlPlaying), new PropertyMetadata(""));
And in my class, i have made an event to see, the new value
private void TBx_StartPt_OnTextChanged(object sender, TextChangedEventArgs e)
{
string newScore = tBx_StartPt.Text;
}
In debug, newScore get the new value.
I don't understand, anything does not display in GUI.
Thank you for your help.

You dependency property declaration is wrong. It must look like this:
public string Score
{
get { return (string)GetValue(ScoreProperty); }
set { SetValue(ScoreProperty, value); }
}
public static readonly DependencyProperty ScoreProperty =
DependencyProperty.Register(
nameof(Score),
typeof(string),
typeof(UserControlPlaying),
new PropertyMetadata(""));
And fix the binding in the textbox:
<TextBox Text="{Binding RelativeSource={RelativeSource AncestorType=UserControl},
Path=Score,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" .../>

Related

Binding property of MainViewModel to SubView

I'm trying to figure out how to bind a property from my MainWindowViewModel to a ContentControl that is based on another View.
RelativeSource Binding seems not to work since the View is in another xaml file?
I tried with dependancy property but I didn't understand how to do this correctly I guess.
What I want to achieve here is that when I type in the TextBox of the MainWindow that all 3 views (contentcontrols) also view the updated data. It should be a demo to illustrate that in MVVM the ViewModel can change without knowledge of the Views and different Views react to it.
Sadly RelativeSource Binding and DependancyProperty didn't work for me or I missed a point.
MainWindow.xaml
<Window x:Class="MVVMDemo.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"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<TextBlock Text="MVVM Demo" HorizontalAlignment="Center" FontSize="20" FontWeight="Bold"/>
<TextBox Text="{Binding TestString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="200" Background="Black" Foreground="White" Margin="0 20 0 0"/>
<Grid Margin="0 20 0 0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="300"/>
</Grid.RowDefinitions>
<ContentControl Grid.Column="0" Grid.Row="0" Content="{Binding ViewOne}"/>
<ContentControl Grid.Column="1" Grid.Row="0" Content="{Binding ViewTwo}"/>
<ContentControl Grid.Column="2" Grid.Row="0" Content="{Binding ViewThree}"/>
</Grid>
</StackPanel>
</Window>
MainWindowViewModel
public class MainWindowViewModel : ViewModelBase
{
/// <summary>
/// String to change the reaction of views
/// </summary>
private string _TestString;
public string TestString
{
get { return _TestString; }
set { _TestString = value; NotifyPropertyChanged(); }
}
private object _ViewOne { get; set; }
public object ViewOne
{
get { return _ViewOne; }
set { _ViewOne = value; NotifyPropertyChanged(); }
}
private object _ViewTwo { get; set; }
public object ViewTwo
{
get { return _ViewTwo; }
set { _ViewTwo = value; NotifyPropertyChanged(); }
}
private object _ViewThree { get; set; }
public object ViewThree
{
get { return _ViewThree; }
set { _ViewThree = value; NotifyPropertyChanged(); }
}
public MainWindowViewModel()
{
ViewOne = new ViewOne();
ViewTwo = new ViewTwo();
ViewThree = new ViewThree();
TestString = "ABC";
}
}
ViewOneViewModel
<UserControl x:Class="MVVMDemo.Views.ViewOne"
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:MVVMDemo.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="White">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=TestString, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Foreground="Black"/>
<TextBlock Text="{Binding TestStringProperty}" Foreground="Black"/>
</StackPanel>
</Grid>
</UserControl>
ViewOneViewModel
public class ViewOneViewModel : ViewModelBase
{
// this doesn't help
public static readonly DependencyProperty TestStringProperty =
DependencyProperty.Register("TestString", typeof(string), typeof(MainWindowViewModel), new PropertyMetadata(null));
}
I believe your issue lies here:
<TextBlock Text="{Binding Path=TestString, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Foreground="Black"/>
Binding Path=TestString should instead be Binding Path=DataContext.TestString as the RelativeSource is looking at the window now, not the window's model.

WPF Binding to a DependencyProperty problem with an custom User Control inside a Window

I need some help. I created a custom User Control, and inserted it into the Main Window. However, Im not able to bind a Property in the Window to a DependencyProperty in the User Control.
Here's the User Control code.
XAML:
<UserControl x:Class="SomeExample.UCFullName"
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:SomeExample"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<StackPanel Margin="0,0,0,0" Orientation="Vertical" >
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<StackPanel Orientation="Vertical">
<Label BorderBrush="White" BorderThickness="1" Content="First Name :" FontSize="14" FontWeight="SemiBold" Foreground="White" Height="30" HorizontalAlignment="Left" Margin="0,2,0,0" VerticalAlignment="Top" Width="100"/>
</StackPanel>
<Grid>
<TextBox Name="FirstName" BorderBrush="Black" BorderThickness="1" FontSize="14" FontWeight="SemiBold" Height="30" HorizontalAlignment="Left" Margin="2,2,0,0" MaxLength="20" VerticalAlignment="Top" Width="100" TextChanged="TxtBlock_TextChanged"/>
</Grid>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<StackPanel Orientation="Vertical">
<Label BorderBrush="White" BorderThickness="1" Content="Last Name :" FontSize="14" FontWeight="SemiBold" Foreground="White" Height="30" HorizontalAlignment="Left" Margin="0,2,0,0" VerticalAlignment="Top" Width="100"/>
</StackPanel>
<Grid>
<TextBox Name="LastName" BorderBrush="Black" BorderThickness="1" FontSize="14" FontWeight="SemiBold" Height="30" HorizontalAlignment="Left" Margin="2,2,0,0" MaxLength="20" VerticalAlignment="Top" Width="100" TextChanged="TxtBlock_TextChanged"/>
</Grid>
</StackPanel>
</StackPanel>
And here's the code behind
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
namespace SomeExample
{
public partial class UCFullName : UserControl, INotifyPropertyChanged
{
#region INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
protected void Notify(string propertyName)
{
if (this.PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion INotifyPropertyChanged implementation
public string ValueFullName
{
get { return (string)GetValue(ValueFullNameProperty); }
set
{
SetValue(ValueFullNameProperty, value);
Notify("ValueFullName");
}
}
// Using a DependencyProperty as the backing store for Value. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ValueFullNameProperty =
DependencyProperty.Register("ValueFullName", typeof(string), typeof(UCFullName), new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public UCFullName()
{
InitializeComponent();
}
private void TxtBlock_TextChanged(object sender, TextChangedEventArgs e)
{
ValueFullName = FirstName.Text + " " + LastName.Text;
}
}
}
This is how it looks:
And here's the code of the Main Window:
<Window x:Class="SomeExample.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:SomeExample"
mc:Ignorable="d"
Title="Some Example" Height="200" Width="400">
<StackPanel Margin="0,0,0,0" Orientation="Vertical" Name="SpManual" Background="Black">
<GroupBox Header="Name" Foreground="White" FontSize="14" Name="groupBoxCoordinateStart" >
<local:UCFullName ValueFullName="{Binding Path = PropertyFullName, Mode = TwoWay, RelativeSource={RelativeSource AncestorType=UserControl}}"></local:UCFullName>
</GroupBox>
<StackPanel Name="SpBtnInsert" Orientation="Horizontal" HorizontalAlignment="Center" Visibility="Visible">
<Button Name="btnShowFullName" BorderBrush="White" BorderThickness="1" FontSize="14" FontWeight="SemiBold" Height="30" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,2,0,0" Background="Transparent" Content="Show Name" Foreground="White" Width="98" Click="BtnShowFullName_Click"></Button>
</StackPanel>
</StackPanel>
And the code behind:
using System.Windows;
namespace SomeExample
{
/// <summary>
/// Lógica de interacción para MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public string PropertyFullName { get; set; }
public MainWindow()
{
InitializeComponent();
}
private void BtnShowFullName_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Current full name :" + PropertyFullName);
}
}
}
And of course, I expected that when I pressed the button, I got a message with the full name entered by the user. However, I got nothing.
Edit: Here's the solution to the problem, for people who visit this page with a similar problem.
<local:UCFullName ValueFullName="{Binding Path = PropertyFullName, RelativeSource={RelativeSource AncestorType=Window}}"></local:UCFullName>
You are binding to the wrong AncestorType. Instead of UserControl the type must be Window. Window extends Control but not UserControl.
<local:UCFullName ValueFullName="{Binding Path=PropertyFullName, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=Window}}" />
Also because you set the Binding.Mode to TwoWay, the binding source PropertyFullName must be able to notify the binding target ValueFullName about value changes. To achieve this, you need to implement PropertyFullName as a DependencyProperty to enable two way binding.
As a a side note:
The following code can be problematic
public string ValueFullName
{
get { return (string)GetValue(ValueFullNameProperty); }
set
{
SetValue(ValueFullNameProperty, value);
Notify("ValueFullName"); // This line might never get called
}
}
This is just a CLR wrapper for the actual DependencyProperty and will never be invoked by the framework. When using the binding on this property the wrapper will never get called and therefore the event will never get raised.
As BionicCode has pointed out, you can change the AncestorType. Another option is to set DataContext of the Window.
You can either do it in the constructor
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
or in the XAML.
<Window DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}}">
This way you don't have to specify source in your bindings (as long as you bind to code-behind properties).

Custom UserControl Template with Property-Binding

I created an custom UserControl which includes an Ellipse and a Label. The Label Content and the Color of the Ellipse is binded:
The Binding-Properties are DependencyProperties.
The color of the Ellipse is depended on the Status, which is a bool (a converter creates the Color)
This is the UserControl1.xaml:
<UserControl x:Class="Plugin_UPS.Views.UserControl1"
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:Converters="clr-namespace:WPF_Prism.Infrastructure.Converters.Ups;assembly=WPF_Prism.Infrastructure"
mc:Ignorable="d"
x:Name="UC1"
d:DesignWidth="200" Height="40">
<UserControl.Resources>
<ResourceDictionary>
<Converters:BoolToColorConverter x:Key="BoolToColorConverter"/>
</ResourceDictionary>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Height="42" Width="504">
<StackPanel HorizontalAlignment="Left" Margin="0,0,0,0" Height="Auto" Width="Auto" Grid.Column="0" Grid.Row="0">
<Grid Height="Auto" Width="Auto" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,0,0,0"
MinWidth="200" MaxWidth="200" MinHeight="35" MaxHeight="40">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Ellipse HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Column="0" Grid.Row="0"
Fill="{Binding Status, Converter={StaticResource BoolToColorConverter}, UpdateSourceTrigger=PropertyChanged}"
Height="15"
Width="15"
StrokeThickness="1"
Stroke="Black">
</Ellipse>
<Label Content="{Binding Text}" Height="Auto" Width="Auto" Margin="0,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="16" Grid.Column="1" Grid.Row="0" />
</Grid>
</StackPanel>
</Grid>
</UserControl>
This is the UserControl1.xaml.cs:
namespace Plugin_UPS.Views
{
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(UserControl1));
public bool Status
{
get { return (bool)GetValue(StatusProperty); }
set { SetValue(StatusProperty, value); }
}
public static readonly DependencyProperty StatusProperty =
DependencyProperty.Register("Status", typeof(bool), typeof(UserControl1));
}
}
This is my UPSViewModel.cs:
namespace Plugin_UPS.ViewModel
{
public class UPSViewModel
{
public UPSViewModel()
{
}
public string UpsModelText { get { return "Model"; } }
private bool replaceBatteryCondition;
public bool ReplaceBatteryCondition { get { return replaceBatteryCondition; } set { replaceBatteryCondition = value; } }
}
}
This is my UPSView.xaml:
(here I implement the UserControl1)
<UserControl x:Class="Plugin_UPS.Views.UPSView"
x:Name="UPSUC"
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:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
xmlns:local="clr-namespace:Plugin_UPS"
xmlns:Controls="clr-namespace:WPF_Prism.Controls.Controls;assembly=WPF_Prism.Controls"
xmlns:ViewModel="clr-namespace:Plugin_UPS.ViewModel"
xmlns:Views="clr-namespace:Plugin_UPS.Views"
d:DataContext="{d:DesignInstance ViewModel:UPSViewModel}"
mc:Ignorable="d"
d:DesignHeight="840" d:DesignWidth="1260">
<Grid>
<StackPanel>
<Views:UserControl1 Margin="10,20,10,10" DataContext="{Binding RelativeSource={RelativeSource Self}}" Text="{Binding UpsModelText}" Status="{Binding ReplaceBatteryCondition}"></Views:UserControl1>
</StackPanel>
</Grid>
</UserControl>
But the binding for "Status" and "Text" is not working.
(Status="True" or Text="Model" is working).
Do you have any ideas what the problem could be?
Is there a problem with the DataContext?
best regards
Phil
You must not set the UserControl's DataContext to itself, as done by
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Remove that assignment and write
<Views:UserControl1 Margin="10,20,10,10"
Text="{Binding UpsModelText}"
Status="{Binding ReplaceBatteryCondition}" />
Now you'll have to specify the source of the bindings in the UserControl's XAML.
There are multiple ways to do that, one of them is to set the RelativeSource property like this:
<Label Content="{Binding Text,
RelativeSource={RelativeSource AncestorType=UserControl}}" ... />
<Ellipse Fill="{Binding Status,
RelativeSource={RelativeSource AncestorType=UserControl},
Converter={StaticResource BoolToColorConverter}}" ... />
Note that setting UpdateSourceTrigger=PropertyChanged on the Fill Binding doesn't make sense.

Binding to custom buttons

I have a self-made button that has image and text.
<ButtonImageApp:ButtonImage
BText="Button"
This works fine. But when I try to to do binding my button code is broken.
This wont work.
BText="{Binding Path=LocalizedResources.PlayButton, Source={StaticResource LocalizedStrings}}"
XAML
<Button x:Class="ButtonImageApp.ButtonImage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
IsEnabledChanged="ButtonIsEnabledChanged"
MouseEnter="ButtonMouseEnter"
MouseLeave="ButtonMouseLeave">
<Grid>
<Image Stretch="None"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Row="0" Grid.Column="0"
x:Name="image" />
<TextBlock x:Name="txtButtonText"
Foreground="Black"
Text="{Binding Path=BText}"
Grid.Row="0" Grid.Column="0"
Margin="20,51,0,-51" TextAlignment="Center"></TextBlock>
</Grid>
</Button>
The Code:
public static readonly DependencyProperty ButtonText = DependencyProperty.Register("BText", typeof(string), typeof(ButtonImage), null);
public string BText
{
get { return (string)GetValue(ButtonText); }
set
{
SetValue(ButtonText, value);
txtButtonText.Text = value;
}
}
The problem is that when using binding the setter of the property is not called.
Instead you need to register for the dependency property changed:
public static readonly DependencyProperty ButtonText = DependencyProperty.Register("BText", typeof(string), typeof(ButtonImage), new PropertyMetadata(ButtonTextChanged));
private static void ButtonTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
txtButtonText.Text = e.NewValue;
}

WPF Bind Textboxes Text On Usercontrol to Dependency but Use different Bindings on Window

So I'm playing around with some WPF UserControls and DependencyProperties.
I've got the following UserControl:
<UserControl x:Class="ValueInser.UserControls.FirmPersonInsert"
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:self="clr-namespace:ValueInser.UserControls"
x:Name="uc1"
mc:Ignorable="d"
d:DesignHeight="225" d:DesignWidth="450"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100px"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition IsEnabled="{Binding ElementName=rbtnPers, Path=IsChecked}"/>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<GroupBox Grid.Column="1" Header="Privat-/Juristische Person" Width="150" HorizontalAlignment="Left">
<StackPanel Orientation="Horizontal">
<RadioButton Content="Person" IsChecked="{Binding Path=IsCompany}"/>
<Line Height="1" Width="25" />
<RadioButton Content="Firma" Name="rbtnCompany" />
</StackPanel>
</GroupBox>
<Label Content="Firma" Grid.Column="0" Grid.Row="1" />
<TextBox Grid.Column="1" Grid.Row="1" Text="{Binding Path=Company}" IsEnabled="{Binding ElementName=rbtnCompany, Path=IsChecked}"/>
<Label Content="Anrede" Grid.Column="0" Grid.Row="2" />
<TextBox Grid.Column="1" Grid.Row="2" Text="{Binding Path=Salutation}" />
<Label Content="Name" Grid.Column="0" Grid.Row="3" />
<TextBox Grid.Column="1" Grid.Row="3" Text="{Binding Path=LastName, RelativeSource={RelativeSource self}}" />
<Label Content="Vorname" Grid.Column="0" Grid.Row="4" />
<TextBox Grid.Column="1" Grid.Row="4" Text="{Binding Path=FirstName}"/>
<Label Content="Strasse" Grid.Column="0" Grid.Row="5" />
<TextBox Grid.Column="1" Grid.Row="5" Text="{Binding Path=Street}" />
<Label Content="Ort" Grid.Column="0" Grid.Row="6" />
<TextBox Grid.Column="1" Grid.Row="6" Text="{Binding Path=City}" />
<Label Content="PLZ" Grid.Column="0" Grid.Row="7" />
<TextBox Grid.Column="1" Grid.Row="7" Text="{Binding Path=ZIP}" />
</Grid>
With this Code Behind:
#region Dependency Properties
public static readonly DependencyProperty _company = DependencyProperty.Register("Company", typeof(string), typeof(UserControl));
public string Company
{
get
{
return this.GetValue(_company) as string;
}
set
{
this.SetValue(_company, value);
}
}
public static readonly DependencyProperty _salutation = DependencyProperty.Register("Salutation", typeof(string), typeof(UserControl));
public string Salutation
{
get
{
return this.GetValue(_salutation) as string;
}
set
{
this.SetValue(_salutation, value);
}
}
public static readonly DependencyProperty _lastName = DependencyProperty.Register("LastName", typeof(string), typeof(UserControl));
public string LastName
{
get
{
return this.GetValue(_lastName) as string;
}
set
{
this.SetValue(_lastName, value);
}
}
public static readonly DependencyProperty _firstName = DependencyProperty.Register("FirstName", typeof(string), typeof(UserControl));
public string FirstName
{
get
{
return this.GetValue(_firstName) as string;
}
set
{
this.SetValue(_firstName, value);
}
}
public static readonly DependencyProperty _street = DependencyProperty.Register("Street", typeof(string), typeof(UserControl));
public string Street
{
get
{
return this.GetValue(_street) as string;
}
set
{
this.SetValue(_street, value);
}
}
public static readonly DependencyProperty _city = DependencyProperty.Register("City", typeof(string), typeof(UserControl));
public string City
{
get
{
return this.GetValue(_city) as string;
}
set
{
this.SetValue(_city, value);
}
}
public static readonly DependencyProperty _zip = DependencyProperty.Register("ZIP", typeof(string), typeof(UserControl));
public string ZIP
{
get
{
return this.GetValue(_zip) as string;
}
set
{
this.SetValue(_zip, value);
}
}
public static readonly DependencyProperty _isCompany = DependencyProperty.Register("IsCompany", typeof(bool), typeof(UserControl));
public bool IsCompany
{
get
{
return !(bool)this.GetValue(_isCompany);
}
set
{
this.SetValue(_isCompany, value);
}
}
#endregion
And now the tricky part comes to play.
So that I can bind the textboxs text property to the dependencyproperties in the code behind I have to set the datacontext to itself.
When I want to use this control now on a Window I have a problem:
<uc:FirmPersonInsert DataContext="{DynamicResource ResourceKey=mvm}"
IsCompany="{Binding Path=ProjectArchitect.IsCompany}"
Company="{Binding Path=ProjectArchitect.Company}"
LastName="{Binding Path=ProjectArchitect.LastName}"
FirstName="{Binding Path=ProjectArchitect.FirstName}"
Street="{Binding Path=ProjectArchitect.Street}"
City="{Binding Path=ProjectArchitect.City}"
ZIP="{Binding Path=ProjectArchitect.ZIP}"/>
This Properties are stored on the ViewModel of the Application. But now the whole construct starts to get weired.
I can't change the datacontext because otherwise the bindings on the usercontrol won't work anymore.
I think I missunderstand something completly how all of that should work.
I need the dependencyprops so that a user of my control can simply bind to the new "Property Names" like LastName.
Please can someone explain me, where am I thinking wrong ?
Remove the DataContext="{Binding RelativeSource={RelativeSource Self}}"> from the usercontrol and instead:
<Grid DataContext="{Binding ElementName=uc1}">.
Also remove all the RelativeSources from the individual textboxes.

Categories

Resources