How to to get Parent's DataContext inside TextBox.Template? - c#

The Label.Binding outside TextBox.Template does work fine but when I want to bind ViewModel.Value to the TextBox inside TextBox.Template then I always get
Error: 40 : BindingExpression path error: 'ViewModel' property not found on 'object'
Is there a way to set the DataContext inside TextBox.Template to the DataContext from the Parent?
<Style TargetType="{x:Type fields:CustomDateFieldView}">
<Label Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ViewModel.Label}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type fields:CustomDateFieldView}">
....
<TextBox.Template>
<ControlTemplate>
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ViewModel.Value}"/>
....
</Stackpanel>
</ControlTemplate>
</TextBox.Template>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<Style TargetType="{x:Type fields:CustomDateFieldView}">
<Label Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ViewModel.Label}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type fields:CustomDateFieldView}">
....
<TextBox.Template>
<ControlTemplate>
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding ViewModel.Value, ElementName = myControlName}"/>
....
</Stackpanel>
</TextBox.Template>
If you give an x:Name to your CustomDateFieldView control, you can use this approach. In my example i put as ElementName myControlName. This require that myControlName.DataContext is your viewmodel of course
EDIT: if the first approach doesn't work, you can try this:
<Style TargetType="{x:Type fields:CustomDateFieldView}">
<Label Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ViewModel.Label}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type fields:CustomDateFieldView}">
....
<TextBox.Template>
<ControlTemplate>
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding ViewModel.Value, RelativeSource={RelativeSource AncestorType={x:Type fields:CustomDateFieldView}}}"/>
....
</Stackpanel>
</TextBox.Template>

Related

Empty Password Property after customizing Passwordbox with ControlTemplate in ResourceDictionary

I've customized my projects TextBox via a ResourceDictionary.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<Style x:Key="TextBoxTheme" TargetType="{x:Type TextBox}">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border CornerRadius="10"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="2"
Background="#FF62B6CB">
<Grid>
<TextBox VerticalContentAlignment="Center"
HorizontalContentAlignment="Left"
Padding="5,0,5,0"
Background="Transparent"
BorderThickness="0"
Foreground="#1B4965"
Margin="1"
TextWrapping="Wrap"
FontWeight="Bold"
Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Text, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="TextWrapping" Value="Wrap" />
</Style.Setters>
</Style>
now I'm trying to add the same design to the Passwordbox
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<Style x:Key="PasswordBoxTheme" TargetType="{x:Type PasswordBox}">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="PasswordBox">
<Border CornerRadius="10"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="2"
Background="#FF62B6CB">
<Grid>
<PasswordBox VerticalContentAlignment="Center"
HorizontalContentAlignment="Left"
Padding="5,0,5,0"
Background="Transparent"
BorderThickness="0"
Foreground="#1B4965"
Margin="1"
FontWeight="Bold" />
<!--Password="{Binding RelativeSource= {RelativeSource TemplatedParent}, Path=Password, UpdateSourceTrigger=PropertyChanged}"/-->
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
The Problem I'm having is that the Password Property of my Passwordbox is empty even though I entered a password. How can I access the Password?
WPF does not bind to the Password proptery of the PasswordBox in fact internally, but always to a DependencyProperty with the name "< nameYouSpecified >Property". If you look at the PasswordBox class there are some DependencyProperties.
For examle:
public static readonly DependencyProperty CaretBrushProperty;
But you will not find a
public static readonly DependencyProperty PasswordProperty;
where WPF could bind to.
Long story short: The Password is not bindable.

Show ToolTip (with custom style) of TextBlock Text

I've got the following problem. I have a DataGrid with a DataGridTemplateColumn and I want to display the text of a cell with a popup (because it can be trimmed).
This is my xaml code:
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock
Text="{Binding Description}"
TextTrimming="CharacterEllipsis">
<TextBlock.ToolTip>
<ToolTip Style="{StaticResource ToolTipBrowserDescription}" ToolTip="test"/>
</TextBlock.ToolTip>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Style:
<Style TargetType="{x:Type ToolTip}" x:Key="ToolTipBrowserDescription">
<Setter Property="DataContext" Value="{Binding RelativeSource={x:Static RelativeSource.Self}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolTip}">
<Border BorderBrush="{StaticResource HT_Background_DarkGrey}" Background="{StaticResource HT_Background_LightGrey3}" BorderThickness="1">
<TextBlock Text="{Binding ToolTip}" FontWeight="Bold" TextWrapping="Wrap" Margin="5" MinWidth="50" MaxWidth="{TemplateBinding MaxWidth}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
But when I'm setting the ToolTip Property from "test" to "{Binding Description}" the ToolTip (which is shown) is empty.
Has anyone the solution for me. I'm stuck for about 2h..
This should do the trick.
ToolTipStyle:
<Style x:Key="ToolTipBrowserDescription"
TargetType="{x:Type ToolTip}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolTip}">
<Border BorderBrush="{StaticResource HT_Background_DarkGrey}"
Background="{StaticResource HT_Background_LightGrey3}"
BorderThickness="1">
<TextBlock Text="{TemplateBinding Content}"
FontWeight="Bold"
TextWrapping="Wrap"
Margin="5"
MinWidth="50"
MaxWidth="{TemplateBinding MaxWidth}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
TextBlock:
<TextBlock Text="{Binding Description}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip Style="{StaticResource ToolTipBrowserDescription}"
Content="{Binding Description}"/>
</Setter.Value>
</Setter>
</Style>
</TextBlock.Style>
</TextBlock>
You should Template-Bind to content, instead to ToolTip of the ToolTip

WPF Resource section not effecting my Label control in the view

I have created a style for a “required field” label which should place a red asterisk “*” in front of the label. Here is my xaml taken from the Application.Resources section of my WPF application:
<Style TargetType="Label" x:Key="RequiredField">
<Setter Property="Margin" Value="0,0,5,0" />
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="Content">
<Setter.Value>
<ControlTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="*" Foreground="Red" FontSize="10"/>
<TextBlock Text="{Binding}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The xaml in my view uses the resource like this:
<Label Grid.Row="1" Grid.Column="0" Style="{StaticResource RequiredField}" Content="Name:"/>
Annoyingly it doesn’t appear to modify the label. Can anyone tell me what I’ve done wrong?
Well your style seems to be wrong. I would try it that way.
<Style TargetType="Label" x:Key="RequiredField">
<Setter Property="Margin" Value="0,0,5,0" />
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Label}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="*" Foreground="Red" FontSize="10"/>
<TextBlock Text="{TemplateBinding Content}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This should do the trick, but it's totally untested.
The template is assigned to the Content property. That is wrong.
Instead it can be assigned to the Template property but in this case it might be better to use the Validation.ErrorTemplate property because it is meant for validation adorners.
From this article:
<ControlTemplate x:Key="TextBoxErrorTemplate">
<StackPanel>
<StackPanel Orientation="Horizontal">
<Image Height="16" Margin="0,0,5,0"
Source="Assets/warning_48.png"/>
<AdornedElementPlaceholder x:Name="Holder"/>
</StackPanel>
<Label Foreground="Red" Content="{Binding ElementName=Holder,
Path=AdornedElement.(Validation.Errors)[0].ErrorContent}"/>
</StackPanel>
</ControlTemplate>
<TextBox x:Name="Box"
Validation.ErrorTemplate="{StaticResource TextBoxErrorTemplate}">

Is there any way to set a tooltip inside an ErrorTemplate?

In our WPF application we have a common control template which we use to display errors in a consistent way
<ResourceDictionary>
<ControlTemplate x:Key="ErrorTemplate">
<Border BorderThickness="1" BorderBrush="Red">
<AdornedElementPlaceholder />
</Border>
</ControlTemplate>
</ResourceDictionary>
Elsewhere in our application when a control might display an error we set the ErrorTemplate like so
<TextBox Validation.ErrorTemplate="{DynamicResource ErrorTemplate}" />
I now want to display a tool tip in this error template, however setting the tooltip property on the border doesn't help that much as the tooltip only displays when the user mouses over the 1px wide border, not the control itself which is in error.
I know that I can set the tooltip in a style, however this error template is applied to many different controls (combo boxes etc...) and many of these controls also use styles which are independent from my error template - I really want to be able to apply my error template in a generic way to any control.
Is there any way that I can set a tooltip in my ErrorTemplate?
I have a style defined. I have IDataErrorInfo on my object (Customer) which does the validation for the property(LastName) which is databound to a text box for example. Here's my style:
<Style x:Key="ValidationTextBox" TargetType="{x:Type Control}">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="0,2,40,2"/>
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="True">
<Border Background="#B22222" DockPanel.Dock="Right" Margin="5,0,0,0" Width="20" Height="20" CornerRadius="10"
ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
<TextBlock Text="!" VerticalAlignment="Center" HorizontalAlignment="Center" FontWeight="Bold" Foreground="White"/>
</Border>
<AdornedElementPlaceholder Name="customAdorner" VerticalAlignment="Center">
<Border BorderBrush="#B22222" BorderThickness="1" />
</AdornedElementPlaceholder>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style
<TextBox Style="{StaticResource ValidationTextBox}" Text="{Binding Path=Customer.LastName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnTargetUpdated=True, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" />
As I stated in my answer here you can:
<ControlTemplate x:Key="ErrorTemplate">
<Border BorderThickness="1" BorderBrush="Red"
Background="Transparent"
ToolTip="{Binding Path=/ErrorContent}">
<AdornedElementPlaceholder />
</Border>
</ControlTemplate>
I'm sorry I didn't have time yesterday...Would you try below and see if this is what you are after, please?
<Style x:Key="ValidationTextBox2" TargetType="{x:Type Control}">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="Red" BorderThickness="2">
<DockPanel LastChildFill="True" ToolTip="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}" Background="Transparent">
<TextBlock />
<AdornedElementPlaceholder Name="customAdorner" VerticalAlignment="Center">
</AdornedElementPlaceholder>
</DockPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

WPF listbox empty item template not showing

I am try to list some data in WPF listbox control. It is the first time I am using DataTemplate in WPF. Everything is working fine except when there is no data it is not showing 'No items to display'. Below is my code.
<ListBox Name="itemsCtrl" Background="#FFE5E5E5" BorderBrush="{x:Null}" SelectionChanged="itemsCtrl_SelectionChanged" Style="{StaticResource ListStyle}">
<ListBox.Resources>
<!-- Set SelectedItem Background here -->
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#C2C2C2"/>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver,
RelativeSource={RelativeSource
Self}}"
Value="True">
<Setter Property="Background"
Value="#C2C2C2" />
</DataTrigger>
</Style.Triggers>
</Style>
<Style TargetType="ListBox" x:Key="ListStyle" BasedOn="{StaticResource {x:Type ListBox}}">
<Style.Triggers>
<DataTrigger
Binding="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=Items.Count}"
Value="0"
>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<TextBlock>No items to display</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Cursor="Hand" Name="hoverDataTemplate" Orientation="Horizontal" Width="370" VerticalAlignment="Top" Height="40" HorizontalAlignment="Left" >
<Label VerticalContentAlignment="Center" HorizontalAlignment="Left" Padding="15,5,5,5" Width="330" Content="{Binding Path=EVENT_TITLE}" FontSize="12"/>
<Image Height="28" Source="/pr;component/Images/black_next.png" Stretch="Fill" Width="28" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And I am binding data source as shown below.
itemsCtrl.ItemsSource = dao.SelectDataTable(cmd).DefaultView;
When I set the style property of ListBox as ListStyle it is throwing an error
'Provide value on 'System.Windows.StaticResourceExtension' threw an exception.' Line number '292' and line position '22'.
Can anybody point out how to make it correct?
Thanks in advance.
i have used below code and it's work fine
my xaml code
<ListBox Grid.ColumnSpan="2" Grid.Row="1" Height="32" HorizontalAlignment="Left" Margin="160,2,0,0" Name="listBox1" VerticalAlignment="Top" Width="120" Style="{StaticResource Dhaval}"/>
Style look like
<Style x:Key="Dhaval" TargetType="{x:Type ListBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Items.Count}" Value="0">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<TextBlock>No items to display</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>

Categories

Resources