【问题标题】:Update UserControl UI with a binding property使用绑定属性更新 UserControl UI
【发布时间】:2016-06-15 21:56:01
【问题描述】:

我有一个带有可以绑定属性的 UserControl。此属性需要更新 UserControl UI。 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>

用户控制代码隐藏 (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

如果我将属性设置为

hexview.rawstring = "This is a sample property"

UserControlUI 已更新,因为它使用 setter 访问器并执行 Parse() 方法。但是使用数据绑定不会。

b任何反馈将不胜感激。

谢谢

【问题讨论】:

    标签: wpf vb.net data-binding user-controls


    【解决方案1】:

    Ryan Flohr's answer会做你想做的,但既然他提到了长篇大论的方法,我想我也会提出长篇大论的方法。啰嗦的方法绝对是推荐的方法。

    后面的代码:

    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>
    

    【讨论】:

    • 这是一个很好的答案,但是有一个小错误。在xaml中,由于你在后面的代码上绑定了一个Dependency Property,所​​以需要将Binding指定为RelativeSource,否则不起作用。
    • 我编辑了你的答案,StackOverflow 说一旦有人同行评审它就会显示出来。
    【解决方案2】:

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

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

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

    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
    

    我对你的问题的正确回答有点啰嗦:

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

    我希望这会有所帮助!

    【讨论】:

    • PropertyChangeCallback 的解决方案有效。谢谢大家。尽管如此,在 UserControl 的 UI 上引用控件的优点和缺点是什么?为什么在控件上使用依赖属性是一种更好的方法?另外,我问我用两个文本块简化了问题,而实际上我在谈论 256 ......它会改变方法吗?谢谢
    【解决方案3】:

    编写一个 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

    【讨论】:

    • 以我的拙见,我觉得这个答案并没有触及问题的核心问题。问题是在设置 DependencyProperty 时要调用“Parse”方法,但是,只有在使用后面的代码而不是绑定设置 DependencyProperty 时才会调用此“Parse”方法。我不明白在这里使用 ValueConverter 是否合适。
    • @RyanFlohr 在这种特殊情况下,使用转换器是正确的方法。
    • 其实可以的。 @RyanFlohr 这完全消除了使用 Parse() 方法的需要。
    • 每种方法各有利弊。 DependencyProperty 方法将向使用HexView 的人公开两个额外的DependencyProperties,他们可以直接绑定到它们,并意外地更改文本块的值。使用转换器可以避免这个问题,但是您可能会使用一个转换器,您可能只用于此控件,有时很难决定将转换器放置在哪个文件夹中。
    猜你喜欢
    • 1970-01-01
    • 2016-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    相关资源
    最近更新 更多