问题
I have a rather simple user control (RatingControl) that has a dependency property defined as follows:
public partial class RatingControl : UserControl
{
public RatingControl()
{
InitializeComponent();
}
public static readonly DependencyProperty RatingValueProperty = DependencyProperty.Register("RatingValue", typeof(double), typeof(RatingControl), new PropertyMetadata(0.0));
public double RatingValue
{
set
{
double normalizeValue = 0.0;
if (value > 10.0)
{
normalizeValue = 10.0;
}
else if (value > 0.0)
{
normalizeValue = value;
}
SetValue(RatingValueProperty, normalizeValue);
RenderRatingValue();
}
get { return (double)GetValue(RatingValueProperty); }
}
...
This control receives properly the RatingValue if I assign it directly:
<gtcontrols:RatingControl RatingValue="2.0" />
However, if I try to assign it with data binding, it does not work. The "set" code for RatingValue is never called, nor I see data binding errors in the debug output window. Note below that I tried to assign the same value to a standard property (Width), and in that case the value is properly passed to it.
<StackPanel>
<TextBox Name="Test" Text="200.0" />
<gtcontrols:RatingControl Width="{Binding ElementName=Test, Path=Text}" RatingValue="{Binding ElementName=Test, Path=Text}" />
<TextBlock Text="{Binding ElementName=Test, Path=Text}" />
</StackPanel>
Not only the TextBlock receives the value correctly. also RatingControl receives is for the width, properly set at 200 pixels; however, the RatingValue is not set (method set not even called)
What am I missing? Thanks in advance.
回答1:
The thing is that the binding system does not use the CLR property wrapper (getter and setter) to assign the value of a dependency property. Those are there just for convenience, so you could use the property just like a normal property in your code. Internally it uses SetValue()/GetValue() methods.
So, the proper place for the value normalization would be the property changed callback for the dependency property:
public static readonly DependencyProperty RatingValueProperty =
DependencyProperty.Register("RatingValue", typeof(double), typeof(RatingControl),
new PropertyMetadata(0.0, new PropertyChangedCallback(RatingValuePropertyChanged))));
static void RatingValuePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var ratingControl = (RatingControl)sender;
var val = (double)e.NewValue;
double normalizeValue = 0.0;
if (val > 10.0)
{
normalizeValue = 10.0;
}
else if (val > 0.0)
{
normalizeValue = val;
}
ratingControl.RatingValue = normalizeValue;
}
来源:https://stackoverflow.com/questions/6808670/windows-phone-7-silverlight-user-control-data-binding-not-working-on-custom-pro