将控件绑定到WPF中的多个属性

本文关键字:属性 WPF 控件 绑定 | 更新日期: 2023-09-27 18:13:53

首先,如果这个问题很愚蠢,我很抱歉,但我是WPF的新手,并且在使用一些控件时遇到了一些困难。

我有一个图像编辑器应用程序,这个应用程序有几个图像缩放控件,如反转,旋转,缩放,亮度和对比度。

要编辑控件,用户选择他们想要编辑的控件,例如亮度,然后沿着图像的一侧出现滑块(否则会隐藏)。

这个滑块目前直接绑定到我的ViewModel的亮度属性。

我希望能够重用这个滑块控件,但动态设置绑定,例如,当我选择缩放控件时,相同的滑块将改变缩放,等等。

我应该使用某种空属性,这是一个指向另一个属性的指针,可以交换出来,当我需要吗?

我不熟悉WPF,但我相信有一种更整洁的方法来排序。

任何帮助都将非常感激。

目前我拥有的是这样的

xml滑块控件

<Slider Grid.Row="0" IsSelectionRangeEnabled="True"  SelectionStart="50" SelectionEnd="150" Grid.Column="1" Orientation="Vertical" Minimum="0" Maximum="200" Value="{Binding Brightness}" Visibility="{Binding IsBrightnessAndContrastEnabled, Converter={StaticResource VisibilityConverter}}">

IsBrightnessAndContrastEnabled是一个简单的bool值,用于决定是否显示滑块,

private int _brightness = 100;
    public int Brightness
    {
        get {  return _brightness;}
        set
        {
            if (_brightness != value)
            {
                Set(() => Brightness, ref _brightness, value);
                ChangeBrightnessAndContrastCommand.Execute(null);
            }
        }
    }

将控件绑定到WPF中的多个属性

首先,我同意Silvermind的观点,最好把它放在不同的滑块中。但回答你的问题,是的,你所要求的是可能的。你只需要一个滑动条用于两个属性。最好的方法是通过创建第三个属性来实现视图模型中的逻辑,这个属性负责改变亮度和对比度。我把这个属性命名为Value:

public int Value
{
    get
    {
        return _value; 
    }
    set
    {
        if (_value != value)
        {
            Set(() => Value, ref _value, value);
            ApplyChanges(_value);
        }                
    }
}

每次值改变时,它调用ApplyChanges方法,这将根据选择的控件更新亮度或对比度。

void ApplyChanges(int value)
{       
    if(_selectedControl.Equals("brightness") && this.Brightness != value)
        this.Brigtness = value; 
    else if(_selectedControl.Equals("contrast") && this.Contrast != value)
        this.Contras = value; 
}

您说用户将选择他们喜欢使用的控件。被选控件本身是我们需要跟踪的另一个属性。你需要知道在你的视图模型中哪个控件被选中,这样你就知道当Value改变时你应该更新哪个(亮度/对比度)。在我的例子中,为了简单起见,我将使用一个字符串,这将告诉视图模型哪个被选中。

public string SelectedControl
{
    get {  return _selectedControl;}
    set
    {
        if (_selectedControl != value)
        {
            Set(() => Contrast, ref _selectedControl, value);
            if(_selectedControl.Equals("brightness"))
                this.Value = this.Brightness;
            else if(_selectedControl.Equals("contrast"))
                this.Value = this.Contrast;
        }
    }
}

每次所选控件发生变化时,如果用户选择了另一个控件,我们将更新Value属性并传递当前所选控件的值。当用户将对比度设置为3,然后将亮度设置为20,然后再次选择对比度时,滑块值应该回到3或对比度的值。每次选定的控件更改时,滑动条中的值也会更新。

最后你需要将属性Value绑定到Slider的值。

我会使用多个滑块,但是为它们创建一个包含所有共享属性的单独样式。这样可以减少代码,使其更易于阅读/维护。

<Style x:Key="MySliderStyle" TargetType="{x:Type Slider}">
    <Setter Property="IsSelectionRangeEnabled" Value="True" />
    <Setter Property="SelectionStart" Value="0" />
    <Setter Property="SelectionEnd" Value="150" />
    <Setter Property="Orientation" Value="Vertical" />
    <Setter Property="Minimum" Value="0" />
    <Setter Property="Maximum" Value="200" />
</Style>
<Slider Style="{DynamicResource MySliderStyle}" Grid.Row="0" Grid.Column="1" 
        Value="{Binding Brightness}" Visibility="{Binding IsBrightnessAndContrastEnabled, Converter={StaticResource VisibilityConverter}}">

如果你真的想使用相同的滑块,你可以动态地改变分配给滑块控件的样式,并让不同的样式定义Binding和Visibility的值。

<Style x:Key="BrightnessSlider" TargetType="{x:Type Slider}" BasedOn="{DynamicResource MySliderStyle}">
    <Setter Property="Value" Value="{Binding Brightness}" />
    <Setter Property="Visibility" Value="{Binding IsBrightnessAndContrastEnabled, Converter={StaticResource VisibilityConverter}}" />
</Style>
<Slider x:Name="MySingleSlider" Grid.Row="0" Grid.Column="1">

在后面的代码中或者在你切换滑块的时候使用的代码中

MySingleSlider.Style = this.FindResource("BrightnessSlider") as Style;

您也可以结合使用这两种方法并创建如#2中定义的样式,但在XAML中使用单独的滑块,如#1中所述。然后你的XAML就更简单了,你可以为每个滑块定制它们各自风格的属性。

<Slider Style="{DynamicResource BrightnessSlider}" Grid.Row="0" Grid.Column="1">

(你也可以将Grid.RowGrid.Column属性放在<Style>中,但通常它们与你布局控件的方式有关,所以我更喜欢将这些属性保留在控件中)