Reputation: 123
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
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
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
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