我的项目是在MVVM中实现的。我有一个MainWindow,它由状态栏和tabview组成。在tabview中,有一个名为" AnnotationView"的UserControl。 Annotationview是两个较小的用户控件的父级,称为TimePicker。 TimePicker由两个文本框组成,一个用于小时,一个用于分钟。我想两次使用这个UserControl(这也是为什么我把它作为自己的控件,以后再重用它)。
TimePicker的XAML:
<UserControl x:Class="archidb.Views.TimePicker"
x:Name="TimePickerControl"
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"
mc:Ignorable="d" Height="Auto" Width="Auto"
KeyboardNavigation.TabNavigation="Local">
<Grid DataContext="{Binding ElementName=TimePickerControl}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="5"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBox Style="{StaticResource TextBoxStyle}"
Text="{Binding Path=HourValue}"
x:Name="tbHours"
KeyboardNavigation.TabIndex="0"/>
<TextBlock Style="{StaticResource TextBlockStyle}"
Margin="0 -3 0 5"
Text=":"
Grid.Column="1"/>
<TextBox Grid.Column="2" Style="{StaticResource TextBoxStyle}"
Text="{Binding Path=MinuteValue}"
x:Name="tbMinutes"
KeyboardNavigation.TabIndex="1"/>
</Grid>
</UserControl>
TimePicker Code-Behind:
public partial class TimePicker : UserControl
{
public static readonly DependencyProperty HourValueProperty = DependencyProperty.Register("HourValue", typeof(string), typeof(TimePicker), new PropertyMetadata("00"));
public string HourValue
{
get { return (string)GetValue(HourValueProperty); }
set { SetValue(HourValueProperty, value); }
}
public static readonly DependencyProperty MinuteValueProperty = DependencyProperty.Register("MinuteValue", typeof(string), typeof(TimePicker), new PropertyMetadata("00"));
public string MinuteValue
{
get { return (string)GetValue(MinuteValueProperty); }
set { SetValue(MinuteValueProperty, value); }
}
public TimePicker()
{
InitializeComponent();
}
}
在AnnotationControl中,我插入UserControls,如下所示:
<v:TimePicker x:Name="tpStart"
HourValue="{Binding Path=StartHours}"
MinuteValue="{Binding Path=StartMinutes}"
KeyboardNavigation.TabIndex="2"/>
<v:TimePicker x:Name="tpEnde"
HourValue="{Binding Path=EndHours}"
MinuteValue="{Binding Path=EndMinutes}"
KeyboardNavigation.TabIndex="3"
Grid.Row="2"/>
AnnotationControl的DataContext设置为viewmodel,我在其中声明了属性。
问题是,绑定无效。我在依赖项属性中设置的默认值(&#34; 00&#34;)没有显示在任何文本框中。此外,如果我在文本框中写入内容,AnnotationControl的viewmodel中的属性不会更改其值。这个问题已经困扰了我好几天了,我在这里做错了什么?
答案 0 :(得分:2)
解决方案是在UserControl
中使用RelativeSource Binding
,然后不将DataContext
设置为自身:
在你的控制中:
<TextBox Style="{StaticResource TextBoxStyle}" Text="{Binding HourValue, RelativeSource=
{RelativeSource AncestorType={x:Type YourPrefixToBeAdded:TimePickerControl}}}"
x:Name="tbHours" KeyboardNavigation.TabIndex="0" />
<TextBlock Style="{StaticResource TextBlockStyle}" Margin="0 -3 0 5" Text=":"
Grid.Column="1" />
<TextBox Grid.Column="2" Style="{StaticResource TextBoxStyle}" Text="{Binding
MinuteValue, RelativeSource={RelativeSource AncestorType={x:Type
YourPrefixToBeAdded:TimePickerControl}}}" x:Name="tbMinutes"
KeyboardNavigation.TabIndex="1" />
然后,您将能够从控件外部绑定属性数据。
答案 1 :(得分:0)
首先,在UserControl构造函数中,将DataContext设置为自身:
public TimePicker()
{
InitializeComponent();
this.DataContext = this;
}
此外,在用户控件中将其从网格中删除:
DataContext="{Binding ElementName=TimePickerControl}"
用户控件的DataContext已在用户控件中设置,因此当您使用以下代码时:
HourValue="{Binding Path=EndHours}"
您实际上是在询问“在UserControl的DataContext中绑定到EndHours。”
您需要更改绑定,以便查看父窗口的DataContext。为父窗口指定名称并使用以下内容:
HourValue="{Binding DataContext.EndHours, ElementName=windowName}"
答案 2 :(得分:0)
最简单的方法: 删除该行:
DataContext="{Binding ElementName=TimePickerControl}"
这样绑定:
"{Binding ElementName=TimePickerControl, Path=HourValue}"
另一种方式:(清洁)
在TimePicker构造函数中设置它:
(this.Content as FrameworkElement).DataContext = this;
这样绑定:
"{Binding HourValue}"
经过一些阅读后,您的示例应该正常工作,因此我假设您没有为ViewModel实现INotifyPropertyChanged,&#34; 00&#34;未显示,因为绑定工作,属性设置为默认值,其值不会更新。