Question

I'm trying to create a style for a textbox which I want to be able to use throughout my code. My style defines a converter in the binding of the Text property but does not set its path because my bound data may not be named the same wherever I use this style.

<Style x:Key="CustomTextBox" BasedOn="{StaticResource {x:Type TextBox}}"
    TargetType="{x:Type TextBox}">
    <Setter Property="Text">
        <Setter.Value>
            <Binding>
                <Binding.Converter>
                    <CustomTextBoxConverter/>
                </Binding.Converter>
            </Binding> 
        </Setter.Value>
    </Setter>
</Style>

And then the customTextBox would be use like so :

<TextBox Height="28" Name="txtRate" Style="{StaticResource CustomTextBox}"
         MaxLength="5" Text="{Binding Path=BoundData}"/>

When I write the code above, I get an execption that "Two-way binding requires Path or XPath.".

I even tried to create an attached properties that is used in the style binding to reflect this value in the style but I couldn't get working either. See next :

<Converters:SomeConvertingFunction x:Key="CustomTextConverter"/>
<local:CustomAttachedProperties.ReflectedPath x:Key="ReflectedPath"/>

<Style x:Key="CustomTextBox" BasedOn="{StaticResource {x:Type TextBox}}"
    TargetType="{x:Type TextBox}">
    <Setter Property="Text">
        <Setter.Value>
            <Binding Path=ReflectedPath Converter=CustomTextConverter/>
        </Setter.Value>
    </Setter>
</Style>

Used in a page like so :

<TextBox Height="28" Name="txtRate" Style="{StaticResource CustomTextBox}"
         MaxLength="5" CustomAttachedProperty="contextBoundDataAsString"/>

The code for the attached property is :

Public Class CustomAttachedProperties

    Public Shared ReadOnly ReflectedPathProperty As DependencyProperty = 
        DependencyProperty.RegisterAttached("ReflectedPath", GetType(String),
        GetType(CustomAttachedProperties))

    Public Shared Sub SetReflectedPath(element As UIElement, value As String)
        element.SetValue(ReflectedPathProperty, value)
    End Sub

    Public Shared Function GetReflectedPath(element As UIElement) As String
        Return TryCast(element.GetValue(ReflectedPathProperty), String)
    End Function
End Class

When I try to using the above code it compiles fine but it does not seem to do anything on my XAML, like it might be creating different instances of the CustomAttachedProperty.

Sorry for the lenghty question but I thought it should be easy to create custom controls that have their own default converters with WPF... I'm confused!

Was it helpful?

Solution

You can create a UserControl that does this quite simply:

<UserControl x:Class="namespace.MyCustomConverterTextBox">
    <TextBlock Text="{Binding Text, Converter={StaticResource yourconverter}}"/>
</UserControl>

Then declare Text as a DependencyProperty in code-behind:

public partial class MyCustomConverterTextBox : UserControl
{
    public string Text {
        get{return (string) GetValue(TextProperty);} 
        set{SetValue(TextProperty, value);}
    }

    public static readonly DependencyProperty TextProperty = 
        DependencyProperty.Register("Text", typeof(string), typeof(MyCustomConverterBox));
 }

This should be enough to let you use it in your xaml:

<local:MyCustomConverterTextBox Text="{Binding YourBinding}" />

I didn't run this code so there might be typos, but it should be enough to give you an idea how to go about this.

OTHER TIPS

The best way to do this in my opinion, is to create a new class that inherits from TextBox, then override the PropertyMetadata for the Text property, allowing yourself an opportunity to change the value in a Coerce callback.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top