当用户想要拖动Slider时,如何阻止Slider更改其值?

时间:2013-10-09 12:47:16

标签: c# wpf windows events slider

采取这种情况:

  • 我有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;
                }
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

好的,所以这个我的朋友就是为什么他们创造了coersion。

所以,你想要做的是从你控制的值到每个滑块创建一个多重绑定。然后你想强迫这些值来控制它们的价值。

第1步: 从您的班级中删除所有UI代码。

第2步: 创建一个将存储值的数据对象。

第3步: 将这些值多重绑定到单个总值。

第4步: 每当多重绑定发生变化时,强制单个值。

第5步: 创建UI类

第6步: 每次向UI类添加滑块时,都要向数据对象添加一个值并绑定到它。