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

本文关键字:属性 两个 组合 取决于 绑定 | 更新日期: 2023-09-27 18:03:03

我有一个绑定属性的问题。我有组合框,4个文本框,一个滑块和一个类与4个十进制属性-每个属性被绑定到一个文本框。但我有一个问题与滑块-取决于组合框,我希望滑块被绑定到第二个或第四个属性。到目前为止,每次我需要绑定时,我都可以很容易地在XAML中完成它,但是这次我认为这是不可能的。

好的,所以我的类[edit]:

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[编辑]

:

enum TypeOfJoints
    {
        Rotary,
        Sliding,
    }

和我的XAML代码的一部分[EDITED]:

<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();
    }
}

所以现在滑块的值被绑定到属性"fourth",但相反,我想要这个绑定依赖于ComboBox的值-有两个可能的:Second和fourth - fourth是起始值,这就是为什么现在我有静态绑定到属性fourth。但是我想让它在ComboBox值改变的时候变成value second

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

这是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>

注意:确保使用双向绑定的组合框。SelectedValue,以便更新视图模型属性:

<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));
    }
}