I have a question for you: I'm trying to bind 2 strings, one from the user control to the code-behind of the window.
This is the usercontrol style:
<UserControl
x:Class="PasswordManager.Helpers.Resource_UserDefined.TextBox_Hint"
xmlns=";
xmlns:x=";
xmlns:d=";
xmlns:local="clr-name"
xmlns:mc=";
Name="TextBoxUserWindow"
d:DesignHeight="60" d:DesignWidth="800"
mc:Ignorable="d">
<Grid Margin="20,0,20,0">
<TextBox
Name="txtSearchBox"
Padding="0,0,0,3"
VerticalContentAlignment="Center"
Background="{Binding Background, RelativeSource={RelativeSource AncestorType=UserControl}}"
BorderBrush="{Binding BorderColorBrush, RelativeSource={RelativeSource AncestorType=UserControl}}"
BorderThickness="{Binding BorderThickness, RelativeSource={RelativeSource AncestorType=UserControl}}"
FontFamily="{Binding FontFamily, RelativeSource={RelativeSource AncestorType=UserControl}}"
FontSize="{Binding FontSize, RelativeSource={RelativeSource AncestorType=UserControl}}"
Text="{Binding TextBase, RelativeSource={RelativeSource AncestorType=UserControl}}"
TextChanged="txtSearchBox_TextChanged" />
<TextBlock
x:Name="txt_HintBox"
Margin="3,0,0,0"
VerticalAlignment="Center"
Background="Transparent"
FontFamily="{Binding FontFamily, RelativeSource={RelativeSource AncestorType=UserControl}}"
FontSize="{Binding FontSize, RelativeSource={RelativeSource AncestorType=UserControl}}"
FontStyle="{Binding FontStyle, RelativeSource={RelativeSource AncestorType=UserControl}}"
Foreground="{Binding ForegroundColorOverlay, RelativeSource={RelativeSource AncestorType=UserControl}}"
IsHitTestVisible="False"
Text="{Binding Hint, ElementName=TextBoxUserWindow}" />
</Grid>
</UserControl>
This is the code-behind file of the user control:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
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 PasswordManager.Helpers.Resource_UserDefined
{
public partial class TextBox_Hint : UserControl, INotifyPropertyChanged
{
public TextBox_Hint()
{
InitializeComponent();
}
public string TextBase
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); OnPropertyChanged(); }
}
// Using a DependencyProperty as the backing store for TextBase. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("TextBase", typeof(string), typeof(TextBox_Hint));
public string Hint
{
get { return (string)GetValue(HintProperty); }
set { SetValue(HintProperty, value); }
}
// Using a DependencyProperty as the backing store for Hint. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HintProperty = DependencyProperty.Register("Hint", typeof(string), typeof(TextBox_Hint), new PropertyMetadata(""));
public Brush Background
{
get { return (Brush)GetValue(BackgroundProperty); }
set { SetValue(BackgroundProperty, value); }
}
// Using a DependencyProperty as the backing store for background. This enables animation, styling, binding, etc...
public static readonly DependencyProperty BackgroundProperty = DependencyProperty.Register("Background", typeof(Brush), typeof(TextBox_Hint), new PropertyMetadata(Brushes.White));
public Brush BorderColorBrush
{
get { return (Brush)GetValue(BorderColorBrushProperty); }
set { SetValue(BorderColorBrushProperty, value); }
}
// Using a DependencyProperty as the backing store for BorderColorBrush. This enables animation, styling, binding, etc...
public static readonly DependencyProperty BorderColorBrushProperty = DependencyProperty.Register("BorderColorBrush", typeof(Brush), typeof(TextBox_Hint), new PropertyMetadata(Brushes.Black));
public Thickness BorderThickness
{
get { return (Thickness)GetValue(BorderThicknessProperty); }
set { SetValue(BorderThicknessProperty, value); }
}
// Using a DependencyProperty as the backing store for BorderThickness. This enables animation, styling, binding, etc...
public static readonly DependencyProperty BorderThicknessProperty = DependencyProperty.Register("BorderThickness", typeof(Thickness), typeof(TextBox_Hint), new PropertyMetadata(new Thickness(1,1,1,1)));
public Brush ForegroundColorOverlay
{
get { return (Brush)GetValue(ForegroundColorOverlayProperty); }
set { SetValue(ForegroundColorOverlayProperty, value); }
}
// Usando un DependencyProperty come memorizzazione per ForegroundColorOverlay
public static readonly DependencyProperty ForegroundColorOverlayProperty = DependencyProperty.Register("ForegroundColorOverlay", typeof(Brush), typeof(TextBox_Hint), new PropertyMetadata(Brushes.Gray));
public FontFamily FontFamily
{
get { return (FontFamily)GetValue(FontFamilyProperty); }
set { SetValue(FontFamilyProperty, value); }
}
// Using a DependencyProperty as the backing store for FontFamily. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FontFamilyProperty = DependencyProperty.Register("FontFamily", typeof(FontFamily), typeof(TextBox_Hint), new PropertyMetadata(new FontFamily("Arial")));
public FontStyle FontStyle
{
get { return (FontStyle)GetValue(FontStyleProperty); }
set { SetValue(FontStyleProperty, value); }
}
// Using a DependencyProperty as the backing store for FontStyle. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FontStyleProperty = DependencyProperty.Register("FontStyle", typeof(FontStyle), typeof(TextBox_Hint), new PropertyMetadata(FontStyles.Normal));
public Double FontSize
{
get { return (Double)GetValue(FontSizeProperty); }
set { SetValue(FontSizeProperty, value); }
}
// Using a DependencyProperty as the backing store for FontSize. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FontSizeProperty = DependencyProperty.Register("FontSize", typeof(Double), typeof(TextBox_Hint), new PropertyMetadata(20.0));
private void txtSearchBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (string.IsNullOrEmpty(txtSearchBox.Text))
txt_HintBox.Visibility = Visibility.Visible;
else
txt_HintBox.Visibility = Visibility.Hidden;
}
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
I use the user control like this:
<userControls:TextBox_Hint
x:Name="TextBox_Reame"
Height="40"
BorderColorBrush="Black"
BorderThickness="0,0,0,1"
FontFamily="{DynamicResource Abel}"
FontSize="20"
FontStyle="Italic"
ForegroundColorOverlay="Gray"
Hint="Inserisci Il Reame"
TextBase="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type userControls:TextBox_Hint}}, Path=TextBase}">
<userControls:TextBox_Hint.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0.0" Color="White" />
<GradientStop Offset="0.5" Color="#FFE1FFE6" />
<GradientStop Offset="1.0" Color="White" />
</LinearGradientBrush>
</userControls:TextBox_Hint.Background>
</userControls:TextBox_Hint>
This is the string property:
private string _Reame;
public string Reame
{
get { return _Reame; }
set { _Reame = value; OnPropertyChanged(); }
}
Now the problem start. I've tried 1000 times to try to fix the issues but with no response. My question is quite simple I think... how can I get the TextBase value (of the user control) directly into my code-behind of the window where I'm using it?
If I use TextBox_Reame.TextBase
, I can perfectly get the value, but I want to use binding. I'm not interested in view model for this window because the low data values.
Thanks to everyone
I have a question for you: I'm trying to bind 2 strings, one from the user control to the code-behind of the window.
This is the usercontrol style:
<UserControl
x:Class="PasswordManager.Helpers.Resource_UserDefined.TextBox_Hint"
xmlns="http://schemas.microsoft/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft/expression/blend/2008"
xmlns:local="clr-name"
xmlns:mc="http://schemas.openxmlformats./markup-compatibility/2006"
Name="TextBoxUserWindow"
d:DesignHeight="60" d:DesignWidth="800"
mc:Ignorable="d">
<Grid Margin="20,0,20,0">
<TextBox
Name="txtSearchBox"
Padding="0,0,0,3"
VerticalContentAlignment="Center"
Background="{Binding Background, RelativeSource={RelativeSource AncestorType=UserControl}}"
BorderBrush="{Binding BorderColorBrush, RelativeSource={RelativeSource AncestorType=UserControl}}"
BorderThickness="{Binding BorderThickness, RelativeSource={RelativeSource AncestorType=UserControl}}"
FontFamily="{Binding FontFamily, RelativeSource={RelativeSource AncestorType=UserControl}}"
FontSize="{Binding FontSize, RelativeSource={RelativeSource AncestorType=UserControl}}"
Text="{Binding TextBase, RelativeSource={RelativeSource AncestorType=UserControl}}"
TextChanged="txtSearchBox_TextChanged" />
<TextBlock
x:Name="txt_HintBox"
Margin="3,0,0,0"
VerticalAlignment="Center"
Background="Transparent"
FontFamily="{Binding FontFamily, RelativeSource={RelativeSource AncestorType=UserControl}}"
FontSize="{Binding FontSize, RelativeSource={RelativeSource AncestorType=UserControl}}"
FontStyle="{Binding FontStyle, RelativeSource={RelativeSource AncestorType=UserControl}}"
Foreground="{Binding ForegroundColorOverlay, RelativeSource={RelativeSource AncestorType=UserControl}}"
IsHitTestVisible="False"
Text="{Binding Hint, ElementName=TextBoxUserWindow}" />
</Grid>
</UserControl>
This is the code-behind file of the user control:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
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 PasswordManager.Helpers.Resource_UserDefined
{
public partial class TextBox_Hint : UserControl, INotifyPropertyChanged
{
public TextBox_Hint()
{
InitializeComponent();
}
public string TextBase
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); OnPropertyChanged(); }
}
// Using a DependencyProperty as the backing store for TextBase. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("TextBase", typeof(string), typeof(TextBox_Hint));
public string Hint
{
get { return (string)GetValue(HintProperty); }
set { SetValue(HintProperty, value); }
}
// Using a DependencyProperty as the backing store for Hint. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HintProperty = DependencyProperty.Register("Hint", typeof(string), typeof(TextBox_Hint), new PropertyMetadata(""));
public Brush Background
{
get { return (Brush)GetValue(BackgroundProperty); }
set { SetValue(BackgroundProperty, value); }
}
// Using a DependencyProperty as the backing store for background. This enables animation, styling, binding, etc...
public static readonly DependencyProperty BackgroundProperty = DependencyProperty.Register("Background", typeof(Brush), typeof(TextBox_Hint), new PropertyMetadata(Brushes.White));
public Brush BorderColorBrush
{
get { return (Brush)GetValue(BorderColorBrushProperty); }
set { SetValue(BorderColorBrushProperty, value); }
}
// Using a DependencyProperty as the backing store for BorderColorBrush. This enables animation, styling, binding, etc...
public static readonly DependencyProperty BorderColorBrushProperty = DependencyProperty.Register("BorderColorBrush", typeof(Brush), typeof(TextBox_Hint), new PropertyMetadata(Brushes.Black));
public Thickness BorderThickness
{
get { return (Thickness)GetValue(BorderThicknessProperty); }
set { SetValue(BorderThicknessProperty, value); }
}
// Using a DependencyProperty as the backing store for BorderThickness. This enables animation, styling, binding, etc...
public static readonly DependencyProperty BorderThicknessProperty = DependencyProperty.Register("BorderThickness", typeof(Thickness), typeof(TextBox_Hint), new PropertyMetadata(new Thickness(1,1,1,1)));
public Brush ForegroundColorOverlay
{
get { return (Brush)GetValue(ForegroundColorOverlayProperty); }
set { SetValue(ForegroundColorOverlayProperty, value); }
}
// Usando un DependencyProperty come memorizzazione per ForegroundColorOverlay
public static readonly DependencyProperty ForegroundColorOverlayProperty = DependencyProperty.Register("ForegroundColorOverlay", typeof(Brush), typeof(TextBox_Hint), new PropertyMetadata(Brushes.Gray));
public FontFamily FontFamily
{
get { return (FontFamily)GetValue(FontFamilyProperty); }
set { SetValue(FontFamilyProperty, value); }
}
// Using a DependencyProperty as the backing store for FontFamily. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FontFamilyProperty = DependencyProperty.Register("FontFamily", typeof(FontFamily), typeof(TextBox_Hint), new PropertyMetadata(new FontFamily("Arial")));
public FontStyle FontStyle
{
get { return (FontStyle)GetValue(FontStyleProperty); }
set { SetValue(FontStyleProperty, value); }
}
// Using a DependencyProperty as the backing store for FontStyle. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FontStyleProperty = DependencyProperty.Register("FontStyle", typeof(FontStyle), typeof(TextBox_Hint), new PropertyMetadata(FontStyles.Normal));
public Double FontSize
{
get { return (Double)GetValue(FontSizeProperty); }
set { SetValue(FontSizeProperty, value); }
}
// Using a DependencyProperty as the backing store for FontSize. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FontSizeProperty = DependencyProperty.Register("FontSize", typeof(Double), typeof(TextBox_Hint), new PropertyMetadata(20.0));
private void txtSearchBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (string.IsNullOrEmpty(txtSearchBox.Text))
txt_HintBox.Visibility = Visibility.Visible;
else
txt_HintBox.Visibility = Visibility.Hidden;
}
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
I use the user control like this:
<userControls:TextBox_Hint
x:Name="TextBox_Reame"
Height="40"
BorderColorBrush="Black"
BorderThickness="0,0,0,1"
FontFamily="{DynamicResource Abel}"
FontSize="20"
FontStyle="Italic"
ForegroundColorOverlay="Gray"
Hint="Inserisci Il Reame"
TextBase="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type userControls:TextBox_Hint}}, Path=TextBase}">
<userControls:TextBox_Hint.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0.0" Color="White" />
<GradientStop Offset="0.5" Color="#FFE1FFE6" />
<GradientStop Offset="1.0" Color="White" />
</LinearGradientBrush>
</userControls:TextBox_Hint.Background>
</userControls:TextBox_Hint>
This is the string property:
private string _Reame;
public string Reame
{
get { return _Reame; }
set { _Reame = value; OnPropertyChanged(); }
}
Now the problem start. I've tried 1000 times to try to fix the issues but with no response. My question is quite simple I think... how can I get the TextBase value (of the user control) directly into my code-behind of the window where I'm using it?
If I use TextBox_Reame.TextBase
, I can perfectly get the value, but I want to use binding. I'm not interested in view model for this window because the low data values.
Thanks to everyone
Share Improve this question edited Mar 15 at 19:29 marc_s 756k184 gold badges1.4k silver badges1.5k bronze badges asked Mar 15 at 11:31 user27828246user27828246 91 silver badge3 bronze badges 3- So, how you tried? Have you checked How to: Create a Binding in Code? – emoacht Commented Mar 15 at 12:28
- As a note, it is pointless to implement INotifyPropertyChanged in a class with dependency properties. Those properties do already provide change notification. – Clemens Commented Mar 15 at 13:39
- The TextBase Binding looks like a failed attempt to bind the property to itself. What's the point? – Clemens Commented Mar 16 at 7:24
1 Answer
Reset to default 0I'll support @Clemens . I also don't quite understand what you want to do and what doesn't work for you.
I'll assume that you have a ViewModel with a "public string Reame" property in the Data Context.
In that case, the "TextBox_Reame.TextBase" binding should be set to this property, not to itself.
<userControls:TextBox_Hint
x:Name="TextBox_Reame"
Height="40"
BorderColorBrush="Black"
BorderThickness="0,0,0,1"
FontFamily="{DynamicResource Abel}"
FontSize="20"
FontStyle="Italic"
ForegroundColorOverlay="Gray"
Hint="Inserisci Il Reame"
TextBase="{Binding Reame}">
<!--TextBase="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type userControls:TextBox_Hint}}, Path=TextBase}">-->
<userControls:TextBox_Hint.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0.0" Color="White" />
<GradientStop Offset="0.5" Color="#FFE1FFE6" />
<GradientStop Offset="1.0" Color="White" />
</LinearGradientBrush>
</userControls:TextBox_Hint.Background>
</userControls:TextBox_Hint>
I also recommend that you use Custom Control instead of UserControl:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace SOTopics2025.SO.user27828246.question79511053
{
public class TextBox_Hint : TextBox
{
static TextBox_Hint()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(TextBox_Hint), new FrameworkPropertyMetadata(typeof(TextBox_Hint)));
}
public string Hint
{
get => (string)GetValue(HintProperty);
set => SetValue(HintProperty, value);
}
// Using a DependencyProperty as the backing store for Hint. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HintProperty
= DependencyProperty.Register(nameof(Hint),
typeof(string),
typeof(TextBox_Hint),
new PropertyMetadata(string.Empty));
public Brush HintForeground
{
get => (Brush)GetValue(HintForegroundProperty);
set => SetValue(HintForegroundProperty, value);
}
// Usando un DependencyProperty come memorizzazione per ForegroundColorOverlay
public static readonly DependencyProperty HintForegroundProperty
= DependencyProperty.Register(nameof(HintForeground),
typeof(Brush),
typeof(TextBox_Hint),
new PropertyMetadata(Brushes.Gray));
public Visibility HintVisibility
{
get => (Visibility)GetValue(HintVisibilityProperty);
private set => SetValue(HintVisibilityPropertyKey, value);
}
// Using a DependencyProperty as the backing store for Hint. This enables animation, styling, binding, etc...
public static readonly DependencyPropertyKey HintVisibilityPropertyKey
= DependencyProperty.RegisterReadOnly(nameof(HintVisibility),
typeof(Visibility),
typeof(TextBox_Hint),
new PropertyMetadata(Visibility.Visible));
public static readonly DependencyProperty HintVisibilityProperty = HintVisibilityPropertyKey.DependencyProperty;
protected override void OnTextChanged(TextChangedEventArgs e)
{
base.OnTextChanged(e);
HintVisibility = string.IsNullOrEmpty(Text) ? Visibility.Visible : Visibility.Collapsed;
}
}
}
Themes/Generic.xaml:
<SolidColorBrush x:Key="TextBox_Hint.Static.Border" Color="#FFABAdB3"/>
<SolidColorBrush x:Key="TextBox_Hint.MouseOver.Border" Color="#FF7EB4EA"/>
<SolidColorBrush x:Key="TextBox_Hint.Focus.Border" Color="#FF569DE5"/>
<Style TargetType="{x:Type custcont:TextBox_Hint}">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="BorderBrush" Value="{StaticResource TextBox_Hint.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type custcont:TextBox_Hint}">
<Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="True">
<Grid>
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
<TextBlock x:Name="Hint_text" Text="{TemplateBinding Hint}" Foreground="{TemplateBinding HintForeground}"
Visibility="{TemplateBinding HintVisibility}" IsHitTestVisible="False"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox_Hint.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox_Hint.Focus.Border}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
Usage:
<StackPanel>
<FrameworkElement.DataContext>
<local:SomeViewModel Reame="Some text"/>
</FrameworkElement.DataContext>
<local:TextBox_Hint Hint="Inserisci Il Reame" Text="{Binding Reame, UpdateSourceTrigger=PropertyChanged}"
Margin="10"/>
<TextBlock Text="{Binding Reame}"/> <!-- For testing -->
</StackPanel>