如何在用户想要拖动滑块时阻止其值更改
本文关键字:用户 拖动 | 更新日期: 2023-09-27 18:34:30
以这个场景为例:
- 我有 5 个滑块(滑块 1、滑块 2、滑块
- 3、滑块 4 和滑块 5(。
- 我可以给每个滑块一个从 0 到 100 的值,但是...
- 如果将它们的所有值相加,则它们必须共享最多 100 的总和。 IE 如果滑块 1 为 50,滑块
- 2 为 50,则所有其他滑块必须为 0。
- IE 如果滑块 1 为 100,则所有其他滑块必须为 0。
- IE 如果滑块 5 为 90,滑块 2 为 5,滑块 3 为 5,则所有其他滑块必须为 0。
我想这样做,如果我增加滑块,如果所有滑块的总和达到最大值,我就不能超过最大值,但我也希望在这种情况下它无法实际处理事件。具体来说,如果我尝试拖动滑块,我不希望它在这种情况下实际上能够更改该值。现在,我有以下代码,但如果它超过,这实际上会减少值,这与在用户尝试拖动它时限制它更改值不同:
public class MaximumSliderGroup
{
List<Slider> m_sliders = new List<Slider>();
Grid m_containerGrid;
int m_startColumn;
int m_startRow;
int m_startColumnSpan;
int m_startRowSpan;
double m_maximum;
public MaximumSliderGroup(Grid containerGrid, int startColumn, int startRow, int startColumnSpan, int startRowSpan, double maximum)
{
m_containerGrid = containerGrid;
m_startColumn = startColumn;
m_startRow = startRow;
m_startColumnSpan = startColumnSpan;
m_startRowSpan = startRowSpan;
m_maximum = maximum;
}
public void AddNewSlider(bool createNewRow)
{
Slider slider = new Slider();
slider.Maximum = m_maximum;
slider.Minimum = 0;
Grid.SetRow(slider, m_startRow + m_sliders.Count);
Grid.SetColumn(slider, m_startColumn + m_sliders.Count);
Grid.SetColumnSpan(slider, m_startColumnSpan);
Grid.SetRowSpan(slider, m_startRowSpan);
if (createNewRow)
{
RowDefinition rowDefinition = new RowDefinition();
rowDefinition.Height = GridLength.Auto;
m_containerGrid.RowDefinitions.Add(rowDefinition);
}
m_containerGrid.Children.Add(slider);
slider.ValueChanged += slider_ValueChanged;
m_sliders.Add(slider);
}
void slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
Slider senderAsSlider = (Slider)sender;
double count = 0;
foreach (Slider slider in m_sliders)
{
count += slider.Value;
}
if (count > m_maximum)
{
senderAsSlider.Value--;
}
}
}
编辑:刚刚想出了一个按照我的标准看起来可以接受的解决方法。它可能不会阻止事件的发生,但是当您由于舍入而不断尝试拖动它时,它不会闪烁该值。
public class MaximumSliderGroup
{
List<Slider> m_sliders = new List<Slider>();
List<Label> m_labels = new List<Label>();
Grid m_containerGrid;
Grid m_subContainerGrid;
int m_startColumn;
int m_startRow;
int m_startColumnSpan;
int m_startRowSpan;
double m_maximum;
public MaximumSliderGroup(Grid containerGrid, int startColumn, int startRow, int startColumnSpan, int startRowSpan, double maximum)
{
// Set the properties.
m_containerGrid = containerGrid;
m_startColumn = startColumn;
m_startRow = startRow;
m_startColumnSpan = startColumnSpan;
m_startRowSpan = startRowSpan;
m_maximum = maximum;
// Create a new sub-grid for sliders and labels at the specified location within the main grid.
m_subContainerGrid = new Grid();
Grid.SetRow(m_subContainerGrid, m_startRow);
Grid.SetColumn(m_subContainerGrid, m_startColumn);
Grid.SetColumnSpan(m_subContainerGrid, m_startColumnSpan);
Grid.SetRowSpan(m_subContainerGrid, m_startRowSpan);
ColumnDefinition sliderColumn = new ColumnDefinition();
sliderColumn.Width = new GridLength(1, GridUnitType.Star);
m_subContainerGrid.ColumnDefinitions.Add(sliderColumn);
ColumnDefinition textBoxColumn = new ColumnDefinition();
textBoxColumn.Width = GridLength.Auto;
m_subContainerGrid.ColumnDefinitions.Add(textBoxColumn);
m_containerGrid.Children.Add(m_subContainerGrid);
}
public void AddNewSlider(bool createNewRow)
{
// Create a new slider, and add it to the sub-grid.
Slider slider = new Slider();
slider.VerticalAlignment = VerticalAlignment.Center;
slider.VerticalContentAlignment = VerticalAlignment.Center;
slider.Maximum = m_maximum;
slider.Minimum = 0;
if (createNewRow)
{
RowDefinition rowDefinition = new RowDefinition();
rowDefinition.Height = GridLength.Auto;
m_subContainerGrid.RowDefinitions.Add(rowDefinition);
}
Grid.SetRow(slider, m_sliders.Count);
Grid.SetColumn(slider, 0);
slider.ValueChanged += slider_ValueChanged;
m_sliders.Add(slider);
m_subContainerGrid.Children.Add(slider);
// Create a new label, and add it to the sub-grid.
Label label = new Label();
label.Content = "0";
label.FontSize = 20;
label.VerticalAlignment = VerticalAlignment.Center;
label.VerticalContentAlignment = VerticalAlignment.Center;
Grid.SetRow(label, m_labels.Count);
Grid.SetColumn(label, 1);
m_labels.Add(label);
m_subContainerGrid.Children.Add(label);
}
void slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
// Round the slider value.
Slider senderAsSlider = (Slider)sender;
double count = 0;
foreach (Slider slider in m_sliders)
{
count += slider.Value;
}
if (count > m_maximum)
{
senderAsSlider.Value = Math.Round(senderAsSlider.Value - 1);
}
else
{
if (senderAsSlider.Value != 0)
{
senderAsSlider.Value = Math.Round(senderAsSlider.Value);
}
}
// Update the relevant label.
foreach (Label label in m_labels)
{
if (Grid.GetRow(label) == Grid.GetRow(senderAsSlider))
{
label.Content = senderAsSlider.Value;
}
}
}
}
好的,所以我的朋友就是他们创造胁迫的原因。
因此,您要做的是从您控制的值到每个滑块创建多重绑定。然后,您希望强制使用这些值以控制其值。
第 1 步:从类中删除所有 UI 代码。
第 2 步:创建一个将存储值的数据对象。
第 3 步:将这些值多重绑定到单个总值。
第 4 步:每当多重绑定更改时强制单个值。
第 5 步:创建 UI 类
第 6 步:每次向 UI 类添加滑块时,都要向数据对象添加一个值并绑定到该对象。