将控件绑定到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);
}
}
}
首先,我同意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.Row
和Grid.Column
属性放在<Style>
中,但通常它们与你布局控件的方式有关,所以我更喜欢将这些属性保留在控件中)