Silverlight 是否在运行时覆盖设置XAML属性?

Silverlight 是否在运行时覆盖设置XAML属性?,silverlight,xaml,controls,dependency-properties,controltemplate,Silverlight,Xaml,Controls,Dependency Properties,Controltemplate,当我使用以下代码行时,从Silverlight类库实现模板控件 <Style TargetType="local:SliderControl"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:SliderControl"> <Grid x:Name="L

当我使用以下代码行时,从Silverlight类库实现模板控件

<Style TargetType="local:SliderControl">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:SliderControl">
                <Grid x:Name="LayoutRoot" Background="White">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <sdk:Label x:Name="lblLabel" Content="" HorizontalContentAlignment="Center" />
                    <Slider x:Name="sldValue" Grid.Row="1" Orientation="Vertical" />
                    <TextBox x:Name="txtValue" Grid.Row="2" MaxWidth="50" MinWidth="50" Text="{Binding ElementName=sldValue, Path=Value, StringFormat=\{0:N2\}}" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

[TemplatePart(Name = "sldValue", Type = typeof(Slider)), TemplatePart(Name = "lblLabel", Type = typeof(Label))]
public class SliderControl : Control
{
    private Slider _sliderElement;

    private Slider SliderElement
    {
        get  { return _sliderElement; }
        set  {
            if (_sliderElement != null)
                _sliderElement.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(sldValue_ValueChanged);;

            _sliderElement = value;

            if (_sliderElement != null)
                _sliderElement.ValueChanged += new RoutedPropertyChangedEventHandler<double>(sldValue_ValueChanged);
        }
    }

    public event EventHandler<ValueChangingEventArgs> ValueChanging;

    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(double), typeof(SliderControl), new PropertyMetadata(0.0, ValuePropertyChanged));

    private static void ValuePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        if (obj is SliderControl)
        {
            SliderControl sliderUserControl = (SliderControl)obj;
            if (sliderUserControl.SliderElement != null)
            {
                sliderUserControl.SliderElement.Value = (double)args.NewValue;
            }
        }
    }

    public SliderControl()
    {
        this.DefaultStyleKey = typeof(SliderControl);
    }

    private void sldValue_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        if (ValueChanging != null)
        {
            ValueChanging(this, new ValueChangingEventArgs(e.OldValue, e.NewValue));
        }
    }

    public override void OnApplyTemplate()
    {
        SliderElement = GetTemplateChild("sldValue") as Slider;
        base.OnApplyTemplate();
    }
}
我在VS设计视图中看到滑块的值为4。但当我运行应用程序时,滑块从0开始。所以,当我在XAML中更改属性时,我可以看到更改,但我当然也希望在运行时将值设置为4。在这种情况下,DependencyProperty是否覆盖该值

下面是Silverlight类库中的模板控件

<Style TargetType="local:SliderControl">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:SliderControl">
                <Grid x:Name="LayoutRoot" Background="White">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <sdk:Label x:Name="lblLabel" Content="" HorizontalContentAlignment="Center" />
                    <Slider x:Name="sldValue" Grid.Row="1" Orientation="Vertical" />
                    <TextBox x:Name="txtValue" Grid.Row="2" MaxWidth="50" MinWidth="50" Text="{Binding ElementName=sldValue, Path=Value, StringFormat=\{0:N2\}}" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

[TemplatePart(Name = "sldValue", Type = typeof(Slider)), TemplatePart(Name = "lblLabel", Type = typeof(Label))]
public class SliderControl : Control
{
    private Slider _sliderElement;

    private Slider SliderElement
    {
        get  { return _sliderElement; }
        set  {
            if (_sliderElement != null)
                _sliderElement.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(sldValue_ValueChanged);;

            _sliderElement = value;

            if (_sliderElement != null)
                _sliderElement.ValueChanged += new RoutedPropertyChangedEventHandler<double>(sldValue_ValueChanged);
        }
    }

    public event EventHandler<ValueChangingEventArgs> ValueChanging;

    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(double), typeof(SliderControl), new PropertyMetadata(0.0, ValuePropertyChanged));

    private static void ValuePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        if (obj is SliderControl)
        {
            SliderControl sliderUserControl = (SliderControl)obj;
            if (sliderUserControl.SliderElement != null)
            {
                sliderUserControl.SliderElement.Value = (double)args.NewValue;
            }
        }
    }

    public SliderControl()
    {
        this.DefaultStyleKey = typeof(SliderControl);
    }

    private void sldValue_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        if (ValueChanging != null)
        {
            ValueChanging(this, new ValueChangingEventArgs(e.OldValue, e.NewValue));
        }
    }

    public override void OnApplyTemplate()
    {
        SliderElement = GetTemplateChild("sldValue") as Slider;
        base.OnApplyTemplate();
    }
}

我没有看到注册DependencyProperty时声明的Value属性

然后将属性绑定到构造函数中的控件:

public SliderControl(){

   InitializeComponent();

   this.sldValue.SetBinding(Slider.ValueProperty, new Binding()
   {
      Source = this,
      Path = new PropertyPath("Value"),
      Mode = BindingMode.TwoWay
   });
}

我成功了!我只是把gmcalab的解决方案放在OnApplyTemplate中。 多亏了gmcalab

    public override void OnApplyTemplate()
    {
        SliderElement = GetTemplateChild("sldValue") as Slider;
        if (SliderElement != null)
        {
            SliderElement.SetBinding(Slider.ValueProperty, new Binding()
            {
                Source = this,
                Path = new PropertyPath("Value"),
                Mode = BindingMode.TwoWay
            });
        }
        base.OnApplyTemplate();
    }

谢谢你的快速回复。注册DependencyProperty时声明的Value属性未被错误地过帐。我道歉。我立即尝试了您有趣的解决方案,但我正在尝试使用模板控件。我假设,因为OnApplyTemplate尚未被调用,所以在我的模板控件中,我没有将滑块设置为子控件的引用。使用附加属性是个好主意,还是我也在考虑从silder继承整个模板控件并传递所有属性。我想一定有更好的解决办法。