WPF 用户控件数据绑定(bind)不起作用

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

我正在创建一个简单的用户控件,将弹出窗口与 TextView 相结合,这并不疯狂。当我一开始在一个窗口中设置它以设置它的样式时,它工作得很好,但是当我将它移到用户控件中以实际完成它时,它就不能再正常工作了。

我将最小值和最大值传递给控件,​​然后它会自动创建一个数字列表以在该范围内进行选择。在用户控件中,数字列表没有正确绑定(bind),谁知道为什么。也许有人可以看看我的代码。

我已经阅读了很多关于此的其他问题,但真的不知道发生了什么。我的输出窗口中没有任何错误,所以那里没有任何线索。无论如何,这是代码 -

用户控件.xaml

<UserControl x:Class="UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         x:Name="Me"
         DataContext="{Binding RelativeSource={RelativeSource Self}}">

<StackPanel>
    <TextBox Name="myTextbox"
             Height="30"
             Margin="0"
             FontSize="14"
             IsReadOnly="True"
             Padding="5,2"
             Text="{Binding Value}" />
    <Popup x:Name="myPopup"
           PlacementTarget="{Binding ElementName=myTextbox}"
           StaysOpen="True">
        <Popup.Style>
            <Style TargetType="{x:Type Popup}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding ElementName=myTextbox, Path=IsFocused}" Value="True">
                        <Setter Property="IsOpen" Value="True" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Popup.Style>

        <StackPanel>
            <ListView Name="myListView"
                      Height="100"
                      MaxHeight="300"
                      ItemsSource="{Binding List,
                                            UpdateSourceTrigger=PropertyChanged}"
                      SelectionChanged="ListView_SelectionChanged">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <Label Width="100"
                               Height="30"
                               Margin="0"
                               Content="{Binding}"
                               FontFamily="Segoe UI"
                               FontSize="14"
                               Padding="5,2" />
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <Button Width="200" Height="30" />
        </StackPanel>
    </Popup>

</StackPanel>

用户控件.xaml.vb
Imports System.ComponentModel
Imports System.Linq.Expressions
Imports System.Collections.ObjectModel

Class UserControl1

' Dependency Properties
Public Shared ReadOnly ListProperty As DependencyProperty = DependencyProperty.Register("List", GetType(ObservableCollection(Of Integer)), GetType(MainWindow))
Public Shared ReadOnly ValueProperty As DependencyProperty = DependencyProperty.Register("Value", GetType(Integer), GetType(MainWindow))
Public Shared ReadOnly MaxValueProperty As DependencyProperty = DependencyProperty.Register("MaxValue", GetType(Integer), GetType(MainWindow))
Public Shared ReadOnly MinValueProperty As DependencyProperty = DependencyProperty.Register("MinValue", GetType(Integer), GetType(MainWindow))

' Properties
Public Property List As ObservableCollection(Of Integer)
    Get
        Return DirectCast(GetValue(ListProperty), ObservableCollection(Of Integer))
    End Get
    Set(value As ObservableCollection(Of Integer))
        SetValue(ListProperty, value)
    End Set
End Property

Public Property Value As Integer
    Get
        Return DirectCast(GetValue(ValueProperty), Integer)
    End Get
    Set(value As Integer)
        SetValue(ValueProperty, value)

    End Set
End Property

Public Property MaxValue As Integer
    Get
        Return DirectCast(GetValue(MaxValueProperty), Integer)
    End Get
    Set(value As Integer)
        SetValue(MaxValueProperty, value)
    End Set
End Property

Public Property MinValue As Integer
    Get
        Return DirectCast(GetValue(MinValueProperty), Integer)
    End Get
    Set(value As Integer)
        SetValue(MinValueProperty, value)
    End Set
End Property

Private Sub ListView_SelectionChanged(sender As System.Object, e As System.Windows.Controls.SelectionChangedEventArgs)
    Value = List(myListView.SelectedIndex)
End Sub

Private Sub UserControl1_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
    List = New ObservableCollection(Of Integer)

    ' Add all available numbers into the list
    For iCounter As Integer = MinValue To MaxValue
        List.Add(iCounter)
    Next

    ' Set the selected index on the list for the value
    myListView.SelectedIndex = Value - MinValue
End Sub
End Class

仅供引用,当我对此进行测试时,我自己在窗口和用户控件设置中设置了最小值和最大值。

最佳答案

我认为您犯了与我刚开始学习 WPF 时相同的错误。我不能保证这是你的问题的原因,但因为这是我能看到的唯一一个,我会解决它。不幸的是,有很多糟糕的教程和快速示例显示 UserControl.DataContext 的连接。对自己:

DataContext="{Binding RelativeSource={RelativeSource Self}}"

或者:
DataContext = this;

现在,如果您不想 Bind,这是完全可以接受的。到UserControl外部,因为它是连接在后面代码中定义的属性的一种快速简便的方法。然而,当你想 Bind从控件之外的属性,你会发现问题。在这些情况下(如果不是在所有情况下),您应该使用 RelativeSource BindingBind到属性背后的代码:
<TextBox Name="myTextbox" Height="30" Margin="0" FontSize="14" IsReadOnly="True"
    Padding="5,2" Text="{Binding Value, RelativeSource={RelativeSource AncestorType={
    x:Type UserControl1}}}" />

在这个 Binding , UserControl1UserControl 的名称声明属性。这应该在所有内部 Binding 上完成。 s。这样,DataContext未设置为 UserControl ,但 Binding s 仍然找到属性。

你可以找到更多关于RelativeSource来自 RelativeSource MarkupExtension MSDN 上的页面。

关于WPF 用户控件数据绑定(bind)不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19191200/

相关文章:

asp.net - 如何将文本附加到数据绑定(bind)字段?

c# - 模板中的服务器控件如何对数据上下文敏感?

c# - 如何使xaml页面占屏幕全宽

c# - 指定从哪个命名空间绑定(bind)属性

vb.net - Winforms 形式 vb.net 中对象的起始属性

data-binding - MVVM:当我更改对象本身时,如何通知每个对象属性的更改?

c# - 在 Visual Studio 中调试时激活自定义新窗口

c# - 如何在 xaml 中的硬编码值上使用转换器

.net - 在 VB.Net 中进行未经检查的整数加法的最快方法?

xml - 使用 XSLT 重命名节点