我构建了一个简单的WPF UserControl,我想在另一个UserControl中实现几个,同时保持数据绑定。我有一个简单的Debug1窗口,它实现了(1)一个绑定的文本块(仅用于验证数据绑定)&按钮; (2)具有绑定的NumericUpDownBox用户控件的单个实例; (3)包含子用户控件NumericUpDownBox实例的父用户控件的实例。
项目(1)和(2)正在运作。第(3)项没有。我觉得我在父用户控件代码的实现中遗漏了一些东西?我也遇到了一些与我有关的错误(见下文)。
Debug1 Window xaml:
<Window x:Class="Debug1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:CFIT"
mc:Ignorable="d"
Title="Debug1" Height="225" Width="600"
Closing="ClosingDebug1">
<Grid>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Button Name="NextButton" Content="Next" Click="ClickNext" Width="50" />
<TextBox Text="{Binding Path=Years, Mode=TwoWay}" />
</StackPanel>
<local:NumericUpDownBox Grid.Row="1" x:Name="SingleBox" Label="TBD" Increment="2" Value="{Binding Path=Years}"/>
<local:YMDH_TimeControl Grid.Row="2" x:Name="TimeControl" YearsValue="{Binding Path=Years}" />
</Grid>
</Window>
调试窗口VB代码:
Public Class Debug1
Public Mat As New clsMaterial
Sub New() ' Removed for brevity
End Sub
Private Sub ClickNext(sender As Object, e As RoutedEventArgs)
Mat.Lives(0).MSDateOffset.Years = Mat.Lives(0).MSDateOffset.Years + 5
End Sub
End Class
Parent UserControl xaml:
<UserControl x:Class="YMDH_TimeControl"
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:CFIT"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="200" MinHeight="30" MinWidth="160"
Name="YMDH_TimeControl">
<Grid DataContext="{Binding ElementName=YMDH_TimeControl}">
<local:NumericUpDownBox Grid.Column="0" x:Name="Years"/>
</Grid>
</UserControl>
父UserControl VB代码:
Public Class YMDH_TimeControl
Public Shared ReadOnly YearsValueProperty As DependencyProperty = DependencyProperty.Register("YearsValue", GetType(Integer), GetType(YMDH_TimeControl), New FrameworkPropertyMetadata(0, (FrameworkPropertyMetadataOptions.BindsTwoWayByDefault), Nothing, New CoerceValueCallback(AddressOf OnValueChanged)))
Private Shared Function OnValueChanged(d As DependencyObject, value As Object) As Object
If IsNumeric(value) Then
Return CInt(value)
Else
Return Nothing
End If
End Function
Public Property YearsValue As Integer
Get
Return Years.Value
End Get
Set(value As Integer)
Years.Value = value
End Set
End Property
End Class
Child UserControl xaml:
<UserControl x:Class="NumericUpDownBox"
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:CFIT"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="50" MinHeight="30" MinWidth="40"
Name="NumericUpDownBox">
<Grid DataContext="{Binding ElementName=NumericUpDownBox}">
<Grid.Resources>
... removed for brevity...
</Grid.Resources>
<!--Box Definition-->
<Border Style="{StaticResource SectionNameBorder}" Grid.Column="0">
<Grid Background="Gray" >
<Viewbox>
<TextBlock Name="LabelTextBlock" Text="{Binding Path=Label, ElementName=NumericUpDownBox}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Viewbox>
<Grid Grid.Row="2" Background="White" >
<Grid Grid.Column="0" HorizontalAlignment="Right">
<Viewbox>
<TextBox Name="ValueTextBox" BorderBrush="White" Text="{Binding Path=Value, Mode=TwoWay, ElementName=NumericUpDownBox, UpdateSourceTrigger=PropertyChanged}" />
</Viewbox>
</Grid>
<Grid Grid.Column="1">
<RepeatButton Name="UpArrow" Style="{StaticResource UpArrowStyle}" Tag="+" Click="TickValues" />
<RepeatButton Name="DownArrow" Style="{StaticResource DownArrowStyle}" Tag="-" Click="TickValues" />
</Grid>
</Grid>
</Grid>
</Border>
</Grid>
</UserControl>
Child UserControl VB代码:
Public Class NumericUpDownBox
Private Const DefaultInc As Integer = 1
Public Sub New()
InitializeComponent()
If Increment = 0 Then Increment = DefaultInc
End Sub
Private Sub TickValues(sender As Object, e As RoutedEventArgs)
Dim Sign As Char
Dim Tag As String
Tag = sender.tag.ToString
If Len(Tag) = 0 Then Exit Sub
Sign = Left(Tag, 1)
If Sign = "+" Then
Value = Value + Increment
ElseIf Sign = "-" Then
Value = Value - Increment
End If
End Sub
Public Property Value As Integer
Get
Return CInt(GetValue(ValueProperty))
End Get
Set(value As Integer)
If value < 0 Then value = 0
SetValue(ValueProperty, value)
End Set
End Property
Public Property Label As String
Get
Return GetValue(LabelProperty)
End Get
Set(value As String)
SetValue(LabelProperty, value)
End Set
End Property
Public Property Increment As Integer
Get
Return CInt(GetValue(IncProperty))
End Get
Set(value As Integer)
If value < 0 Then value = 0
SetValue(IncProperty, value)
End Set
End Property
Public Shared ReadOnly ValueProperty As DependencyProperty = DependencyProperty.Register("Value", GetType(Integer), GetType(NumericUpDownBox), New FrameworkPropertyMetadata(0, (FrameworkPropertyMetadataOptions.BindsTwoWayByDefault), Nothing, New CoerceValueCallback(AddressOf OnValueChanged)))
Public Shared ReadOnly LabelProperty As DependencyProperty = DependencyProperty.Register("Label", GetType(String), GetType(NumericUpDownBox), New FrameworkPropertyMetadata(""))
Public Shared ReadOnly IncProperty As DependencyProperty = DependencyProperty.Register("Increment", GetType(Integer), GetType(NumericUpDownBox), New FrameworkPropertyMetadata(0, Nothing, New CoerceValueCallback(AddressOf OnValueChanged)))
Private Shared Function OnValueChanged(d As DependencyObject, value As Object) As Object
If IsNumeric(value) Then
Return CInt(value)
Else
Return Nothing
End If
End Function
End Class
输出窗口中的示例信息错误:
System.Windows.Data信息:10:无法使用绑定检索值,并且不存在有效的回退值;使用默认值。 BindingExpression:路径=岁;的DataItem = NULL;目标元素是&#39; YMDH_TimeControl&#39; (名称=&#39; TimeControl&#39);目标财产是“年度值”&#39; (键入&#39; Int32&#39;)
如何让我的数据绑定通过我的父用户控件?