首先,为所有XAML道歉。我已经尝试了几天来解决这个问题,但我必须遗漏一些东西。摘要问题是我的UserControl
依赖项属性在使用时似乎没有在代码隐藏中进行数据绑定。
详细信息:我有以下简单的UserControl
(在它自己的dll中),我使用0..59的滑块选择秒,UserControl
有一个依赖属性{{ 1}}返回Value
,由通过滑块选择的秒数组成:
TimeSpan
使用简单(省略)的xaml:
public partial class TinyTimeSpanControl : UserControl, INotifyPropertyChanged
{
public TinyTimeSpanControl()
{
InitializeComponent();
}
private int _seconds;
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public int Seconds
{
get { return _seconds; }
set
{
if (_seconds == value)
return;
_seconds = value;
RaisePropertyChanged("Seconds");
var t = Value;
Value = new TimeSpan(t.Hours, t.Minutes, _seconds);
}
}
public TimeSpan Value
{
get { return (TimeSpan) GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
private static void OnValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
TinyTimeSpanControl control = obj as TinyTimeSpanControl;
var newValue = (TimeSpan)e.NewValue;
control.Seconds = newValue.Seconds;
}
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
"Value", typeof(TimeSpan), typeof(TinyTimeSpanControl), new PropertyMetadata(OnValueChanged));
}
控件中的绑定工作正常。
现在当我编译它时,然后将<UserControl x:Class="WpfControlLibrary1.TinyTimeSpanControl" x:Name="root">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Slider Name="SecondsSlider"
Width="120"
Height="23"
HorizontalAlignment="Left"
VerticalAlignment="Top"
LargeChange="5"
SelectionStart="0"
SmallChange="1"
Value="{Binding Path=Seconds,
ElementName=root}" SelectionEnd="59" Maximum="59" />
<Label Name="label1"
Grid.Column="1"
Content="{Binding ElementName=SecondsSlider,
Path=Value}" />
<Label Name="label2"
Grid.Column="2"
Content="Seconds" />
</Grid>
</UserControl>
添加到我的一个窗口(省略):
TinyTimeSpanControl
我的主窗口:
<Window x:Class="WpfControls.MainWindow"
xmlns:my="clr-namespace:WpfControlLibrary1;assembly=WpfControlLibrary1"
x:Name="root"
Closing="root_Closing">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="142*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<my:TinyTimeSpanControl Name="tinyTimeSpanControl1"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Value="{Binding ElementName=root,
Path=TheTime}" />
<Label Name="label1"
Grid.Column="1"
Content="{Binding ElementName=tinyTimeSpanControl1,
Path=Value}" />
<Label Name="label2"
Grid.Column="2"
Content="{Binding ElementName=root,
Path=TheTime}" />
</Grid>
</Window>
数据绑定部分有效:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private TimeSpan _theTime = new TimeSpan(0, 0, 33);
public TimeSpan TheTime
{
get
{
return _theTime;
}
set
{
if (_theTime == value)
return;
_theTime = value;
RaisePropertyChanged("TheTime");
}
}
最初在我的主窗口后面的代码中设置为tinyTimeSpanControl1
属性的值TheTime
更新tinyTimeSpanControl1
。但不起作用:
label1
仍设置为原始版本的label2
在TheTime
事件中加入断点表明Window_closing
未发生变化。
我错过了一些我需要在TheTime
中提出的事件吗?
谢谢,并再次为所有xaml道歉(这也是最小的案例)。
答案 0 :(得分:2)
这是问题所在:
Value = new TimeSpan(t.Hours, t.Minutes, _seconds);
这会清除您在窗口中建立的绑定,只需设置一个值即可。在UserControl
代码中,您不应使用SetValue
,而应使用SetCurrentValue
,这样可以保持对该属性的绑定。
其他一些事情也可能会被关闭,我还没看到......