Update UserControl UI with a binding property

I have a UserControl with a property that can be binded to. This property needs to update the UserControl UI. The UserControl has two textblocks and the property needs to update one textblockwith half of the string and the other textblock with the other half.

UserControl XAML:

<UserControl x:Class="HexView"
         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:LearningWPF"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <TextBlock x:Name="txtOne" Width="100" Height="100" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,10,0,0">Hola</TextBlock>
    <TextBlock x:Name="txtTwo" Width="100" Height="100" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="120,10,0,0">Adios</TextBlock>

</Grid>
</UserControl>

UserControl CodeBehind (VB)

Imports System.ComponentModel

Public Class HexView

Private s_Rawstring As String

Public Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
End Sub

Public Shared ReadOnly RawStringProperty As DependencyProperty = DependencyProperty.Register("RawString", GetType(String), GetType(HexView))
Public Property Rawstring As String
    Get
        Return GetValue(RawStringProperty)
    End Get
    Set(value As String)
        SetValue(RawStringProperty, value)
        Parse()
    End Set
End Property

Private Sub Parse()
    txtOne.Text = Rawstring.Substring(0, Rawstring.Length / 2)
    txtTwo.Text = Rawstring.Substring(Rawstring.Length / 2)
End Sub
End Class

If I set the property like

hexview.rawstring = "This is a sample property"

the UserControlUI is updated because it uses the setter accesor and executes the method Parse(). However using databind does not.

bAny feedback will be appreciate.

Thank you

Upvotes: 0

Views: 355

Answers (3)

AnjumSKhan
AnjumSKhan

Reputation: 9827

Write an IValueConverter , which will do the work for you.

class ParseStringConv : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (parameter.ToString() == "Left")
                return value.ToString().Substring(0, value.ToString().Length / 2);

            return value.ToString().Substring(value.ToString().Length / 2);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

Usage :

<TextBlock Text="{Binding Name, Converter={StaticResource ParseConv}, ConverterParameter='Left'}" />

<TextBlock Text="{Binding Name, Converter={StaticResource ParseConv}, ConverterParameter='Right'}" />

Pass the appropriate ConverterParameter.

Upvotes: 0

Jai
Jai

Reputation: 8363

Ryan Flohr's answer would do what you want, but since he mentioned the long-winded method, I guess I would put up the long-winded method as well. The long-winded method is definitely the recommended way to do it.

Code behind:

Imports System.ComponentModel

Public Class HexView

Private s_Rawstring As String

Public Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
End Sub

Public Shared ReadOnly RawStringProperty As DependencyProperty = DependencyProperty.Register("RawString", GetType(String), GetType(HexView), New PropertyMetadata(New PropertyChangedCallback(AddressOf RawStringPropertyChanged)))
Public Property Rawstring As String
    Get
        Return GetValue(RawStringProperty)
    End Get
    Set(value As String)
        SetValue(RawStringProperty, value)
    End Set
End Property

Private Shared Sub RawStringPropertyChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
    Dim control As HexView = CType(d, HexView)
    control.Parse()
End Sub

Public Shared ReadOnly ParsedStringOneProperty As DependencyProperty = DependencyProperty.Register("ParsedStringOne", GetType(String), GetType(HexView), New PropertyMetadata(String.Empty))
Public Property ParsedStringOne As String
    Get
        Return GetValue(ParsedStringOneProperty)
    End Get
    Set(value As String)
        SetValue(ParsedStringOneProperty, value)
    End Set
End Property

Public Shared ReadOnly ParsedStringTwoProperty As DependencyProperty = DependencyProperty.Register("ParsedStringTwo", GetType(String), GetType(HexView), New PropertyMetadata(String.Empty))
Public Property ParsedStringTwo As String
    Get
        Return GetValue(ParsedStringTwoProperty)
    End Get
    Set(value As String)
        SetValue(ParsedStringTwoProperty, value)
    End Set
End Property


Private Sub Parse()
    ParsedStringOne = Rawstring.Substring(0, Rawstring.Length / 2)
    ParsedStringTwo = Rawstring.Substring(Rawstring.Length / 2)
End Sub
End Class

XAML:

<UserControl x:Class="HexView"
         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:LearningWPF"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
  <TextBlock x:Name="txtOne" Width="100" Height="100"
           HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,10,0,0"
           Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:HexView}},Path=ParsedStringOne}"/>
    <TextBlock x:Name="txtTwo" Width="100" Height="100"
           HorizontalAlignment="Left" VerticalAlignment="Top" Margin="120,10,0,0"
           Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:HexView}},Path=ParsedStringTwo}" />

</Grid>
</UserControl>

Upvotes: 2

Ryan
Ryan

Reputation: 1340

When you access a Dependency Property using a Binding, the code behind "Get" and "Set" don't actually get called. The get'r and set'r are simply a wrapper around the "GetValue()" and "SetValue()" as a convenience for code-behind use.

My short answer to your question is the following code changes to at least get it working in its current form:

Leverage the PropertyChangedCallback delegate on your Dependency Property and have it call the "Parse()" method.

Public Shared ReadOnly RawStringProperty As DependencyProperty = DependencyProperty.Register("RawString", GetType(String), GetType(HexView), New PropertyMetadata(New PropertyChangedCallback(AddressOf RawStringPropertyChanged)))
Public Property Rawstring As String
    Get
        Return GetValue(RawStringProperty)
    End Get
    Set(value As String)
        SetValue(RawStringProperty, value)

    End Set
End Property

Private Shared Sub RawStringPropertyChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
    Dim control As HexView = CType(d, HexView)
    control.Parse()
End Sub

My proper answer to your question is a little more long-winded:

While it is legal, you should generally avoid referencing controls by name in your code-behind. For the two strings, you should have dependency properties for each, and then bind the textboxes to them.

I hope this helps!

Upvotes: 2

Related Questions