Wpf 使用绑定属性更新UserControl UI

Wpf 使用绑定属性更新UserControl UI,wpf,vb.net,data-binding,user-controls,Wpf,Vb.net,Data Binding,User Controls,我有一个UserControl,它的属性可以绑定到。此属性需要更新UserControl UI。UserControl有两个textblock,属性需要用字符串的一半更新一个textblock,用另一半更新另一个textblock UserControl XAML: <UserControl x:Class="HexView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

我有一个UserControl,它的属性可以绑定到。此属性需要更新UserControl UI。UserControl有两个textblock,属性需要用字符串的一半更新一个textblock,用另一半更新另一个textblock

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>
如果我将属性设置为

hexview.rawstring = "This is a sample property"
UserControlUI已更新,因为它使用setter accesor并执行Parse()方法。但是,使用数据绑定并不能

如有任何反馈,将不胜感激


谢谢

当您使用绑定访问依赖项属性时,“Get”和“Set”后面的代码实际上不会被调用。get'r和set'r只是“GetValue()”和“SetValue()”的包装器,方便代码隐藏使用

我对您的问题的简短回答是,对以下代码进行更改,以至少使其以当前形式工作:

利用依赖项属性上的PropertyChangedCallback委托,并让它调用“Parse()”方法

我对你问题的正确回答有点冗长:

虽然这是合法的,但通常应避免在代码隐藏中按名称引用控件。对于这两个字符串,您应该为每个字符串都具有依赖项属性,然后将文本框绑定到它们


我希望这有帮助

使用绑定访问依赖项属性时,“Get”和“Set”后面的代码实际上不会被调用。get'r和set'r只是“GetValue()”和“SetValue()”的包装器,方便代码隐藏使用

我对您的问题的简短回答是,对以下代码进行更改,以至少使其以当前形式工作:

利用依赖项属性上的PropertyChangedCallback委托,并让它调用“Parse()”方法

我对你问题的正确回答有点冗长:

虽然这是合法的,但通常应避免在代码隐藏中按名称引用控件。对于这两个字符串,您应该为每个字符串都具有依赖项属性,然后将文本框绑定到它们

我希望这有帮助

的答案可以满足你的要求,但既然他提到了冗长的方法,我想我也会提出冗长的方法。冗长的方法绝对是推荐的方法

代码隐藏:

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:


的答案可以满足你的要求,但既然他提到了冗长的方法,我想我也会提出冗长的方法。冗长的方法绝对是推荐的方法

代码隐藏:

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:


编写一个IValueConverter,它将为您完成这项工作

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();
        }
    }
用法:

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

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


通过相应的
ConverterParameter

编写一个IValueConverter,它将为您完成工作

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();
        }
    }
用法:

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

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


传递相应的
ConverterParameter

这是一个很好的答案,但是存在一个小错误。在xaml中,由于您要绑定到代码背后的依赖项属性,因此需要将绑定指定为相对资源,否则它将不起作用。我编辑了您的答案,StackOverflow说,一旦有人对其进行了检查,它就会显示出来。这是一个很好的答案,但存在一个小错误。在xaml中,由于您要绑定到代码背后的依赖属性,因此需要将绑定指定为相对资源,否则它将不起作用。我编辑了您的答案,StackOverflow说,一旦有人对其进行了审阅,它就会显示出来。依我的拙见,我觉得这个答案并没有触及问题的核心问题。问题是在设置DependencyProperty时需要调用一个“Parse”方法,但是,只有在使用代码隐藏而不是绑定设置DependencyProperty时,才会调用这个“Parse”方法。我不认为在这里使用ValueConverter是合适的。@RyanFlohr在这种特殊情况下使用Converter是正确的方法。实际上它会起作用@RyanFlohr这就完全不需要使用Parse()方法。每种方法都有优点和缺点。DependencyProperty方法将向使用
HexView
的人员公开另外两个DependencyProperty,他们可以直接绑定到该属性,并意外更改textblocks的值。使用converter可以避免这个问题,但是您可能会有一个转换器,您可能只用于此控件,有时很难决定将转换器放置在哪个文件夹中。以我的拙见,我不认为这个答案能够解决问题的核心问题。问题是在设置DependencyProperty时需要调用一个“Parse”方法,但是,只有在使用代码隐藏而不是绑定设置DependencyProperty时,才会调用这个“Parse”方法。我不认为在这里使用ValueConverter是合适的。@RyanFlohr在这种特殊情况下使用Converter是正确的方法。实际上它会起作用@RyanFlohr这就完全不需要使用Parse()方法。每种方法都有优点和缺点。DependencyProperty方法将向使用
HexView
的人员公开另外两个DependencyProperty,他们可以直接绑定到该属性,并意外更改textblocks的值。使用converter可以避免此问题,但您可能会有一个转换器,您可能只会将其用于此控件,有时很难决定将转换器放置在哪个文件夹中。使用PropertyChangeCallback的解决方案是有效的。谢谢大家。尽管如此,在UserControl的UI上引用控件的利弊是什么?为什么在控件上使用依赖属性是一种更好的方法?另外,我问我用两个文本块简化了这个问题,而实际上我说的是256…Do