采取这样的场景:如何阻止滑块在用户想要拖动时更改其值?
- 我有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.
我想使它如此,如果我增加一个滑块,如果所有滑块的总和是不能超过最大值最大限度,但我也希望它不能在这种情况下实际处理事件。具体来说,如果我尝试拖动Slider,我不希望它在这种情况下实际上能够更改该值。现在,我有以下的代码,但是当用户试图将它拖到这实际上减少数值,如果去了,这是不一样的,从改变值收缩它:
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;
}
}
}
}
不应该跳过ValueChanged处理程序中的当前滑块(发件人)以防止出现循环吗? –
@ErnodeWeerd无关紧要,但是,一旦您从一个事件更改中减少一次值,值更改事件将再次进入,并且在此时间点,没有其他更改值,因为它不会再次递减,因为它会低于最大值。 – Alexandru