将Slider值属性绑定到两个类属性之一 - 取决于组合框

时间:2014-05-12 20:00:07

标签: c# wpf binding

我遇到绑定属性的问题。 我有组合框,4个文本框,一个滑块和一个带有4个十进制属性的类 - 每个属性绑定到一个文本框。但我有一个滑块的问题 - 取决于组合框我希望滑块绑定到第二或第四属性。 每次我需要绑定到现在,我都可以轻松地在XAML中进行,但是这次我认为不可能。

好的,我的班级[编辑]:

class Joint : INotifyPropertyChanged
    {
        private decimal _alfa;
        public decimal alfa
        {
            get { return _alfa; }
            set { _alfa = value; OnPropertyChanged(); }
        }
        private decimal _l;
        public decimal l
        {
            get { return _l; }
            set { _l = value; OnPropertyChanged(); } 
        }
        private decimal _lambda;
        public decimal lambda
        {
            get { return _lambda; }
            set { _lambda = value; OnPropertyChanged(); } 
        }
        private decimal _theta;
        public decimal theta 
        {
            get { return _theta; }
            set { _theta = value; OnPropertyChanged(); } 
        }
        private decimal _min;
        public decimal min
        {
            get { return _min; }
            set { _min = value; OnPropertyChanged(); } 
        }
        private decimal _max;
        public decimal max
        {
            get { return _max; }
            set { _max = value; OnPropertyChanged(); }
        }
        private TypeOfJoints _type;
        public TypeOfJoints type
        {
            get { return _type; }
            set { _type = value; OnPropertyChanged(); } 
        }


        public Joint()
        {
            alfa = 1.00M;
            l = 2.00M;
            lambda = 3.00M;
            theta = 140.00M;
            min = -200.00M;
            max = 200.00M;
            type = TypeOfJoints.Rotary;
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName]string propertyName = null)
        {
            PropertyChangedEventHandler propertyChangedEvent = PropertyChanged;
            if (propertyChangedEvent != null)
                propertyChangedEvent(this, new PropertyChangedEventArgs(propertyName));
        }

    }

我的枚举[已编辑]:

enum TypeOfJoints
    {
        Rotary,
        Sliding,
    }

我的XAML代码部分[已编辑]:

<GroupBox Header="Joint 1">
    <StackPanel DataContext="{StaticResource ResourceKey=joint1}">
        <ComboBox SelectedItem="{Binding type, Mode=TwoWay}" ItemsSource="{Binding Source={StaticResource JointEnum}}"/>
        <TextBox Text="{Binding alfa, UpdateSourceTrigger=PropertyChanged}"/>
        <TextBox Text="{Binding l, UpdateSourceTrigger=PropertyChanged}"/>
        <TextBox Text="{Binding lambda, UpdateSourceTrigger=PropertyChanged}"/>
        <TextBox Text="{Binding theta, UpdateSourceTrigger=PropertyChanged}"/>
        <Slider x:Name="slider1" Minimum="{Binding min}" Maximum="{Binding max}" ValueChanged="Slider_ValueChanged">
            <Slider.Resources>
                <local:SliderValueConverter x:Key="SliderValueConverter" />
            </Slider.Resources>
            <Slider.Value>
                <MultiBinding Converter="{StaticResource SliderValueConverter}">
                    <Binding Path="type"/>
                    <Binding Path="lambda"/>
                    <Binding Path="theta"/>
                </MultiBinding>
            </Slider.Value>
        </Slider>
    </StackPanel>
</GroupBox>

还有Validator类:

class SliderValueConverter :IMultiValueConverter
{

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {

        TypeOfJoints type = (TypeOfJoints)values.FirstOrDefault();
        Console.WriteLine(type);
        if (type == TypeOfJoints.Sliding)
                return values.ElementAtOrDefault(1);
        else if (type == TypeOfJoints.Rotary)
                return values.ElementAtOrDefault(2);

        return DependencyProperty.UnsetValue;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

所以现在滑块值被绑定到属性&#34;第四个&#34;,相反,我希望这个绑定依赖于ComboBox值 - 有两种可能:第二和第四 - 第四是起始值那就是为什么现在我有静态绑定属性第四。但是当ComboBox值发生变化时,我希望它更改为第二个值。

1 个答案:

答案 0 :(得分:0)

这是MultiBinding的一个很好用法。设置如下:

<Slider x:Name="slider1" Minimum="{Binding min}" Maximum=" {Binding max}" ValueChanged="Slider_ValueChanged">
    <Slider.Resources>
        <local:SliderValueConverter x:Key="SliderValueConverter" />
    </Slider.Resources>
    <Slider.Value>
        <MultiBinding Converter="{StaticResource SliderValueConverter}">
            <Binding Path="type" />
            <Binding Path="second" />
            <Binding Path="fourth" />
        </MultiBinding>
    </Slider.Value>
</Slider>

注意:确保对ComboBox.SelectedValue使用TwoWay绑定,以便更新视图模型属性:

<ComboBox SelectedItem="{Binding type,Mode=TwoWay}" ItemsSource="{Binding Source={StaticResource NumberEnum}}"/>

最后,将SliderValueConverter实现为IMultiValueConverter,并返回适当的值。

public class SliderValueConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    { 
        vartype = values.FirstOrDefault() as TypeOfJoints?;
        decimal? val1 = values.ElementAtOrDefault(1) as decimal?,
                 val2 = values.ElementAtOrDefault(2) as decimal?;
        if (type.HasValue && val1.HasValue && val2.HasValue)
        {
            if (type.Value == TypeOfJoints.Sliding)
                return val1.Value;
            else if (type.Value == TypeOfJoints.Rotary)
                return val2.Value
        }
        return DependencyProperty.UnsetValue;      // no match - return default;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

修改

另一个问题:对于从视图模型源到更新的绑定,视图模型必须实现INotifyPropertyChanged,并根据需要引发PropertyChanged事件。在这种情况下,我们需要:

class Joint : INotifyPropertyChanged
{
    public decimal first 
    { 
        get { return _first; }
        set { _first = value; OnPropertyChanged(); }
    }
    private decimal _first;

    // and so forth with the other properties ...

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged([CallerMemberName]string propertyName = null)
    {
        PropertyChangedEventHandler propertyChangedEvent = PropertyChanged;
        if (propertyChangedEvent != null)
            propertyChangedEvent(this, new PropertyChangedEventArgs(propertyName));
    }

}