次のシナリオを考えてみましょう。
- 5 つのスライダー (スライダー 1、スライダー 2、スライダー 3、スライダー 4、およびスライダー 5) があります。
- 各スライダーに 0 から 100 の値を指定できますが、...
- すべての値を合計すると、最大で 100 の合計を共有する必要があります。
- つまり、スライダー 1 が 50 で、スライダー 2 が 50 の場合、他のすべてのスライダーは 0 でなければなりません。
- つまり、スライダー 1 が 100 の場合、他のすべてのスライダーは 0 でなければなりません。
- つまり、スライダー 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;
}
}
}
}