I.Katzav

Hello all I am trying to create a custom text box which uses the next template:

<Style TargetType="{x:Type local:XTextBox}">
<
Setter Property="Template">
<
Setter.Value>
<
ControlTemplate TargetType="{x:Type local:XTextBox}">
<
Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<
TextBox x:Name="txtVal" Background="Beige" IsReadOnly="True"
Text="{Binding RelativeSource={x:Static RelativeSource.TemplatedParent}, Path=Text}" />
</
Border>
</
ControlTemplate>
</
Setter.Value>
</
Setter>
</
Style>

I have two problems:

1. I want to add a converter (I know how to do that) to the binding and to add a ConverterParameter (Iknow to do that also), but I want the parameter to be the XTextBox object itself (I need to use its properties). can I do that and how

2. AS you can see the template has a text box with Beige background. I want to add a trigger on the XTextBox property "IsEditable" that will set the Background of the text to be gray when IsEditable=false. for example:

<wpfUtils:XTextBox x:Name="txtValue" Width="100" Height="20" Grid.Row="0" TableName="Candidates" DisplayMember="FirstName + ' ' + LastName"
ValueMember="CandidateID" WhereClause="" IsEditable="false" />

on this scenario I want the background to be gray.

3. This is a general question:

How can I refered to the textbox from the XTextBox CS code, since this textbox is in the template in the generics file.

thanx

Itzik



Re: Windows Presentation Foundation (WPF) Custom Control, Converter parameters, Trigger using parent property

neil mosafi

1. Hmm well the ConverterParameter is not a depedency property so you cannot bind to it. The only way I can think of (and it's not great) is to make your converter a DependencyObject and create a DependencyProperty for your TextBox

e.g.
public class MyConverter : DependencyObject, IValueConverter
{
public static readonly DependencyProperty TextBoxProperty = DependencyProperty.Register("TextBox", typeof(TextBox), typeof(MyConverter));

public TextBox TextBox
{
get { return (TextBox) this.GetValue(TextBoxProperty); }
set { this.SetValue(TextBoxProperty, value)); }
}
....
}

You can then do

<Style TargetType="{x:Type local:XTextBox}">
<Style.Resources>
<my:MyConverter TextBox="{Binding ElementName=txtVal}" x:Key="myConv" />
</Style.Resources>
<
Setter Property="Template">
<
Setter.Value>
<
ControlTemplate TargetType="{x:Type local:XTextBox}">
<
Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<
TextBox x:Name="txtVal" Background="Beige" IsReadOnly="True"
Text="{Binding RelativeSource={x:Static RelativeSource.TemplatedParent}, Path=Text, Converter={StaticResource myConv}}" />
</
Border>
</
ControlTemplate>
</
Setter.Value>
</
Setter>
</
Style>


2. First remove the Background from your TextBox. Then, inside your ControlTemplate, define a ControlTemplate.Triggers as follows

<ControlTemplate.Triggers>
<DataTrigger Binding="{TemplateBinding IsEditable}" Value="True">
<Setter TargetName="txtValue" Property="Background" Value="Beige" />
</DataTrigger>
<DataTrigger Binding="{TemplateBinding IsEditable}" Value="False">
<Setter TargetName="txtValue" Property="Background" Value="Gray" />
</DataTrigger>
</ControlTemplate.Triggers

3. You can use the visual tree helper to traverse the visual tree and find the textbox. However I would not recommend that, as if someone decides to retemplate your XTextBox your code will probably crash!

Note I have written this code off the top of my head so there may be a few errors, but you should get the general idea! Let me know if you have any more questions

Regards
Neil




Re: Windows Presentation Foundation (WPF) Custom Control, Converter parameters, Trigger using parent property

lee d

1. try multibinding. you can use RelativeSource in the binding

RelativeSource={RelativeSource Self}






Re: Windows Presentation Foundation (WPF) Custom Control, Converter parameters, Trigger using parent property

I.Katzav

On the trigger issue I get the next error

Error 1 Cannot find the Trigger target 'txtValue'.  (The target must appear before any Setters, Triggers, or Conditions that use it.) Line 18 Position 53. C:\Users\itzik.katzav.000\Documents\Visual Studio 2005\Projects\WpfUtils\themes\generic.xaml 18 53 WpfUtils

What should I do

<Style TargetType="{x:Type local:XTextBox}">
     <
Setter Property="Template">
          <
Setter.Value>
               <
ControlTemplate TargetType="{x:Type local:XTextBox}">
                    <
ControlTemplate.Triggers>
                         <
DataTrigger Binding="{TemplateBinding IsEditable}" Value="True">
                              <
Setter TargetName="txtValue" Property="Background" Value="Beige" />
                         </
DataTrigger>
                         <
DataTrigger Binding="{TemplateBinding IsEditable}" Value="False">
                              <
Setter TargetName="txtValue" Property="Background" Value="Gray" />
                         </
DataTrigger>
                    </
ControlTemplate.Triggers>
                    <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                    <
TextBox x:Name="txtVal" IsReadOnly="True" Text="{Binding RelativeSource={x:Static RelativeSource.TemplatedParent}, Path=Text}" />
               </
Border>
                </ControlTemplate>

          </
Setter.Value>
     </
Setter>
</
Style>





Re: Windows Presentation Foundation (WPF) Custom Control, Converter parameters, Trigger using parent property

lee d

it is looking for a control with Name 'txtValue', you named the textbox 'txtVal' and move the triggers section

<ControlTemplate TargetType="{x:Type local:XTextBox}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<
TextBox x:Name="txtValue" IsReadOnly="True" Text="{Binding RelativeSource={x:Static RelativeSource.TemplatedParent}, Path=Text}"
/>

<ControlTemplate.Triggers>
<
DataTrigger Binding="{TemplateBinding IsEditable}" Value="True"
>
<
Setter TargetName="txtValue" Property="Background" Value="Beige"
/>
</
DataTrigger
>
<
DataTrigger Binding="{TemplateBinding IsEditable}" Value="False"
>
<
Setter TargetName="txtValue" Property="Background" Value="Gray"
/>
</
DataTrigger
>
</
ControlTemplate.Triggers
>

</
Border
>
</ControlTemplate>






Re: Windows Presentation Foundation (WPF) Custom Control, Converter parameters, Trigger using parent property

I.Katzav

can't do what u wrote this is the exception

Error 7 The attached property 'ControlTemplate.Triggers' is not defined on 'Border' or one of its base classes. C:\Users\itzik.katzav.000\Documents\Visual Studio 2005\Projects\WpfUtils\themes\generic.xaml 15 14 WpfUtils





Re: Windows Presentation Foundation (WPF) Custom Control, Converter parameters, Trigger using parent property

lee d

my mistake that was a typo,move the triggers after border

<ControlTemplate TargetType="{x:Type local:XTextBox}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<
TextBox x:Name="txtValue" IsReadOnly="True" Text="{Binding RelativeSource={x:Static RelativeSource.TemplatedParent}, Path=Text}"
/>

</Border>

<ControlTemplate.Triggers>
<
DataTrigger Binding="{TemplateBinding IsEditable}" Value="True"
>
<
Setter TargetName="txtValue" Property="Background" Value="Beige"
/>
</
DataTrigger
>
<
DataTrigger Binding="{TemplateBinding IsEditable}" Value="False"
>
<
Setter TargetName="txtValue" Property="Background" Value="Gray"
/>
</
DataTrigger
>
</
ControlTemplate.Triggers
>


</ControlTemplate>






Re: Windows Presentation Foundation (WPF) Custom Control, Converter parameters, Trigger using parent property

I.Katzav

Hi again when I hit play and load the control I get this error

Cannot convert the value in attribute 'Binding' to object of type ''. Error at object 'System.Windows.DataTrigger', Line 17 Position 26.

on the InitializeComponent Line

Do U have any Idea





Re: Windows Presentation Foundation (WPF) Custom Control, Converter parameters, Trigger using parent property

lee d

if IsEditable is a property, you could just use triggers(something like this)

<Trigger Property="IsEditable" Value="true">
<Setter Property = "Background" Value="Red"/>
</Trigger>






Re: Windows Presentation Foundation (WPF) Custom Control, Converter parameters, Trigger using parent property

I.Katzav

yes but that will change the border backround rather then the textbox background which is in the border.



Re: Windows Presentation Foundation (WPF) Custom Control, Converter parameters, Trigger using parent property

lee d

Give it a targetname(the name of the textbox)




Re: Windows Presentation Foundation (WPF) Custom Control, Converter parameters, Trigger using parent property

I.Katzav

Hi lee

thanks for trying to help.

this is what i tried to do and got this exception:
Cannot convert the value in attribute 'Binding' to object of type ''. Error at object 'System.Windows.DataTrigger', Line 17 Position 26.

on the InitializeComponent Line

Do U have any Idea

itzik





Re: Windows Presentation Foundation (WPF) Custom Control, Converter parameters, Trigger using parent property

I.Katzav

Here is the full code:

the crash says:

Cannot create instance of 'Window4' defined in assembly 'WindowsApplication4, Version=1.0.2601.26932, Culture=neutral, PublicKeyToken=null'. Exception has been thrown by the target of an invocation. Error in markup file 'Window4.xaml' Line 1 Position 9.

Code:

<Style TargetType="{x:Type local:XTextBox}">
<Setter Property="Template">
<
Setter.Value>
<
ControlTemplate TargetType="{x:Type local:XTextBox}">
<
Border x:Name="brd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<TextBox x:Name="txtVal" IsReadOnly="True" />
</
Border>
<
ControlTemplate.Triggers>
<
DataTrigger Binding="{TemplateBinding IsFocused}" Value="True">
<
Setter TargetName="txtVal" Property="Background" Value="Beige" />
</
DataTrigger>
<DataTrigger Binding="{TemplateBinding IsFocused}" Value="False">
<
Setter TargetName="txtVal" Property="Background" Value="Gray" />
</
DataTrigger>
</
ControlTemplate.Triggers>
</
ControlTemplate>
</
Setter.Value>
</Setter>
</
Style>





Re: Windows Presentation Foundation (WPF) Custom Control, Converter parameters, Trigger using parent property

lee d

look at the inner exception. Any reason why you went back to using DataTrigger




Re: Windows Presentation Foundation (WPF) Custom Control, Converter parameters, Trigger using parent property

I.Katzav

What do u mean by went back. I always tried that. today I have a temporary solution which looks like that:

/// <summary>
/// Apply the template
/// </summary>
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
SetText();
SetBackground();
}

/// <summary>
/// Set the text box background
/// </summary>
private void SetBackground()
{
if (this.Template != null)
{
TextBox txtBox = this.Template.FindName("txtVal", this) as TextBox;
if (IsEditable)
txtBox.Background =
Brushes.Beige;
else
txtBox.Background = Brushes.LightGray;
}
}

But triggers seems more reasnable to me