Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 以XAML为单位设置最小值的绑定滑块值_C#_Wpf_Binding - Fatal编程技术网

C# 以XAML为单位设置最小值的绑定滑块值

C# 以XAML为单位设置最小值的绑定滑块值,c#,wpf,binding,C#,Wpf,Binding,我对WPF绑定行为有些困惑。我在代码隐藏(code behind)中有一个绑定到依赖项属性的滑块值(仅用于示例)。滑块的最小值以XAML为单位设置。加载窗口后,滑块的值设置为最小值,但dependency属性仍具有默认值0。但是,正在调用滑块的ValueChanged回调,因此我实际上希望绑定得到更新 所以我有下面的窗口,一个标签显示滑块值,另一个标签显示值绑定到的属性 <Window x:Class="SliderBinding.MainWindow" x

我对WPF绑定行为有些困惑。我在代码隐藏(code behind)中有一个绑定到依赖项属性的滑块值(仅用于示例)。滑块的最小值以XAML为单位设置。加载窗口后,滑块的值设置为最小值,但dependency属性仍具有默认值0。但是,正在调用滑块的ValueChanged回调,因此我实际上希望绑定得到更新

所以我有下面的窗口,一个标签显示滑块值,另一个标签显示值绑定到的属性

    <Window x:Class="SliderBinding.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525" x:Name="window">
        <StackPanel DataContext="{Binding ElementName=window}">
            <Slider Minimum="10" Maximum="100" x:Name="slider" Value="{Binding SliderValue, Mode=TwoWay}" ValueChanged="Slider_OnValueChanged"/>
            <Label Content="{Binding Value, ElementName=slider}"></Label>
            <Label Content="{Binding SliderValue}"></Label>
        </StackPanel>
    </Window>

后面的代码包含dependency属性和事件回调,事件回调在滑块值更改时只打印跟踪消息

    using System;
    using System.Diagnostics;
    using System.Windows;

    namespace SliderBinding
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {

            public MainWindow()
            {
                InitializeComponent();
            }

            /* Sorry, wrong code
            public double SliderValue
            {
                get; set;
            }*/

            public double SliderValue
            {
                get { return (double)GetValue(SliderValueProperty); }
                set { SetValue(SliderValueProperty, value); }
            }

            public static readonly DependencyProperty SliderValueProperty =
                DependencyProperty.Register("SliderValue", typeof(double), typeof(MainWindow), new PropertyMetadata(default(double)));


            private void Slider_OnValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
            {
                Trace.TraceInformation("Slider value changed to {0}", e.NewValue);
            }
        }
    }
使用系统;
使用系统诊断;
使用System.Windows;
命名空间滑块绑定
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
}
/*对不起,打错了
公共双滑块值
{
获得;设置;
}*/
公共双滑块值
{
获取{return(double)GetValue(SliderValueProperty);}
set{SetValue(SliderValueProperty,value);}
}
公共静态只读DependencyProperty SliderValueProperty=
Register(“SliderValue”、typeof(double)、typeof(MainWindow)、newpropertyMetadata(default(double));
私有无效滑块\u OnValueChanged(对象发送方,RoutedPropertyChangedEventArgs e)
{
Trace.TraceInformation(“滑块值更改为{0}”,e.NewValue);
}
}
}
只要移动滑块,两个值就相等

我的问题是,当滑块值设置为其最小值时,为什么在启动时不更新dependency属性


以斜体编辑。

这里发生的事情是,强制滑动控件的
属性,使其位于
最小值
最大值
属性定义的范围内

加载XAML并连接绑定后,将读取零的
SliderValue
,WPF将尝试设置
属性。但是,由于零不在其他属性定义的范围内,因此提供的值会强制进入该范围,因此
属性保持为10(设置
最小值
属性时给出的值)。因此,从标签绑定中可以看出,
SliderValue
的值保持为0,而滑块的
值保持为10

拖动滑块拇指时,滑块的
属性将更改。这会导致双向绑定更新,但方向相反(从控件到依赖项属性)。由于DP上没有强制,因此其值将设置为滑块的值。从这一点上说,两者是同步的

您可以通过在窗口中添加一个按钮来验证此行为,然后在
OnClick
处理程序中将
SliderValue
设置为滑块范围之外的值。您将看到
SliderValue
发生更改,但由于强制,滑块的值被设置为其最小值或最大值


值强制是可以为依赖项属性配置的功能之一。阅读更多信息。

这里发生的是,滑块控件的
属性被强制,使其位于
最小值
最大值
属性定义的范围内

加载XAML并连接绑定后,将读取零的
SliderValue
,WPF将尝试设置
属性。但是,由于零不在其他属性定义的范围内,因此提供的值会强制进入该范围,因此
属性保持为10(设置
最小值
属性时给出的值)。因此,从标签绑定中可以看出,
SliderValue
的值保持为0,而滑块的
值保持为10

拖动滑块拇指时,滑块的
属性将更改。这会导致双向绑定更新,但方向相反(从控件到依赖项属性)。由于DP上没有强制,因此其值将设置为滑块的值。从这一点上说,两者是同步的

您可以通过在窗口中添加一个按钮来验证此行为,然后在
OnClick
处理程序中将
SliderValue
设置为滑块范围之外的值。您将看到
SliderValue
发生更改,但由于强制,滑块的值被设置为其最小值或最大值


值强制是可以为依赖项属性配置的功能之一。阅读更多信息。

这里发生的是,滑块控件的
属性被强制,使其位于
最小值
最大值
属性定义的范围内

加载XAML并连接绑定后,将读取零的
SliderValue
,WPF将尝试设置
属性。但是,由于零不在其他属性定义的范围内,因此提供的值会强制进入该范围,因此
属性保持为10(设置
最小值
属性时给出的值)。因此<
    public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register(
                    "Value",
                    typeof(double),
                    typeof(RangeBase),
                    new FrameworkPropertyMetadata(
                            0.0d,
                            FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | 
                            FrameworkPropertyMetadataOptions.Journal,
                            new PropertyChangedCallback(OnValueChanged),
                            new CoerceValueCallback(ConstrainToRange)),
                    new ValidateValueCallback(IsValidDoubleValue));

    internal static object ConstrainToRange(DependencyObject d, object value)
    {
        RangeBase ctrl = (RangeBase) d;
        double min = ctrl.Minimum;
        double v = (double) value;
        if (v < min)
        {
            return min;
        }

        double max = ctrl.Maximum;
        if (v > max)
        {
            return max;
        }

        return value;
    }
public static readonly DependencyProperty SliderValueProperty =
    DependencyProperty.Register("SliderValue", typeof(double), typeof(MainWindow),
    new PropertyMetadata(default(double), null, CoerceSliderValue));


private static object CoerceSliderValue(DependencyObject d, object value)
{
    // Of course good idea would be to be have min/max as CLR properies
    // in your class and bind slider with those values.
    // So, that you can have refer to those values directly here.

    double min = ((MainWindow)d).slider.Minimum;
    double max = ((MainWindow)d).slider.Maximum;
    double passedValue = (double)value;

    if (passedValue < min)
    {
        return min;
    }
    else if (passedValue > max)
    {
        return max;
    }
    return passedValue;
}

private void Slider_OnValueChanged(object sender, 
                                   RoutedPropertyChangedEventArgs<double> e)
{
    CoerceValue(SliderValueProperty);
}