1

我是 C# 编程新手,对 C/C++ 有一点背景。我正在尝试编写一个问题,几乎就像一个均衡器,只是在玩代码。想象一下 5 个彼此相邻的垂直滑块,当您上下移动中间滑块时,其他滑块会根据哈希函数对特定值做出反应,我稍后会弄清楚,目前我很简单方程。

但是,当我添加更多滑块时,我不想为每个滑块添加一个函数,所以有没有办法“检测”哪个滑块正在移动,并通过算法发送它来移动相邻的滑块?基本上,我想要一个功能来将相邻的滑块移动到我选择移动的任何滑块上。从逻辑上讲,这是有道理的,但是我不知道如何在代码中做到这一点。

我为特定滑块编写的函数如下。

private void slider3_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        double adjacentSliders = ((slider3.Value) / 4) * 3;
        double adjacentSliders2 = ((slider3.Value) / 2);
        slider2.Value = slider4.Value = adjacentSliders;
        slider1.Value = slider5.Value = adjacentSliders2;
    }

可能我解释的不是很全,有问题可以追问!

4

3 回答 3

3
private void anySlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
   var thisSlider = sender as Slider;
   ...
}

当您需要相邻的滑块时,在 FormLoad 中构建滑块列表。然后,您可以找到索引thisSlider并从那里开始工作。

编辑:我不确定 WPF 是否在更改代码中的值时触发事件。如果是这样,您可能需要这样做来防止它进入循环:

private static bool changingSlider = false;

private void anySlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
    if (! changingSlider)
    {
        changingSlider = true;      
        var thisSlider = sender as Slider;
        ...
        changingSlider = false;
}
于 2013-01-15T18:40:35.563 回答
0

我有一段时间没有使用 C# 和 Visual Studio,所以我不记得在窗口设计器中是否有直接使用数组的方法,有人应该在评论中清除它;)。

但是您可能想要的是,而不是声明slider1,slider2,slider3,...您应该使用一个数组,以便您可以访问slider[0],slider[1],...

为此,您首先必须更改表单的设计以使用数组,然后在处理程序中访问该数组。

没有数组:

        private System.Windows.Forms.TrackBar trackBar1;
        private System.Windows.Forms.TrackBar trackBar2;
        private System.Windows.Forms.TrackBar trackBar3;

        [...]

        this.trackBar1 = new System.Windows.Forms.TrackBar();
        this.trackBar2 = new System.Windows.Forms.TrackBar();
        this.trackBar3 = new System.Windows.Forms.TrackBar();
        ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit();
        ((System.ComponentModel.ISupportInitialize)(this.trackBar2)).BeginInit();
        ((System.ComponentModel.ISupportInitialize)(this.trackBar3)).BeginInit();
        this.SuspendLayout();
        // 
        // trackBar1
        // 
        this.trackBar1.Location = new System.Drawing.Point(154, 80);
        this.trackBar1.Name = "trackBar1";
        this.trackBar1.Size = new System.Drawing.Size(104, 45);
        this.trackBar1.TabIndex = 0;
        // 
        // trackBar2
        // 
        this.trackBar2.Location = new System.Drawing.Point(154, 132);
        this.trackBar2.Name = "trackBar2";
        this.trackBar2.Size = new System.Drawing.Size(104, 45);
        this.trackBar2.TabIndex = 1;
        // 
        // trackBar3
        // 
        this.trackBar3.Location = new System.Drawing.Point(154, 184);
        this.trackBar3.Name = "trackBar3";
        this.trackBar3.Size = new System.Drawing.Size(104, 45);
        this.trackBar3.TabIndex = 2;

带数组:

        private System.Windows.Forms.TrackBar[] trackBar = new System.Windows.Forms.TrackBar[3];

        [...]
        this.SuspendLayout();

        for(int n = 0; n < 3; n++) {
            this.trackBar[n] = new System.Windows.Forms.TrackBar();
            ((System.ComponentModel.ISupportInitialize)(this.trackBar[n])).BeginInit();

            this.trackBar[n].Location = new System.Drawing.Point(154, 80 + n*52);
            this.trackBar[n].Name = "trackBar[" + n + "]";
            this.trackBar[n].Size = new System.Drawing.Size(104, 45);
            this.trackBar[n].TabIndex = 0;
        }

然后您可以通过 trackBar[x] 访问所有轨迹栏。您可以将声明和 for 循环中的 3 更改为您想要的常量或变量。

于 2013-01-15T18:54:34.427 回答
0

您也可以仅在 xaml 中执行此操作。你只需要一个FormulaCalculationConverter. 我试过了,效果很好。

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:WpfApplication2="clr-namespace:WpfApplication2"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <sys:Double x:Key="MyValueFour">4.0</sys:Double>
    <sys:Double x:Key="MyValueTwo">2.0</sys:Double>
    <WpfApplication2:FormulaCalculationConverter x:Key="FormulaCalculationConverter"/>
</Window.Resources>
<StackPanel>
    <Slider x:Name="BaseSlider" />
    <Slider>
        <Slider.Value>
            <MultiBinding Converter="{StaticResource FormulaCalculationConverter}">
                <Binding Path="Value" ElementName="BaseSlider" Mode="OneWay"  />
                <Binding Path="." Source="{StaticResource MyValueFour}" />
            </MultiBinding>
        </Slider.Value>
    </Slider>
    <Slider >
        <Slider.Value>
            <MultiBinding Converter="{StaticResource FormulaCalculationConverter}">
                <Binding Path="Value" ElementName="BaseSlider" Mode="OneWay"  />
                <Binding Path="." Source="{StaticResource MyValueTwo}" />
            </MultiBinding>
        </Slider.Value>
    </Slider>
    <Slider Value="{Binding Path=Value, ElementName=BaseSlider}"/>
</StackPanel>
</Window>

我刚刚创建了一个转换器

public class FormulaCalculationConverter : IMultiValueConverter
{
   // this is incomplete formula converter...
   public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
   {
       // strictly assume for 1 + 1
       double retVal = 0;
       if (values[0] == DependencyProperty.UnsetValue || values[1] == DependencyProperty.UnsetValue
           || values[0] == null || values[1] == null)
       {
           return Binding.DoNothing;
       }
       // apply logic to split formula here
       retVal = System.Convert.ToDouble(values[0]) + System.Convert.ToDouble(values[1]);
       return retVal;
   }

   public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
   {
       throw new NotImplementedException();
   }
}

但是您需要为此使用转换器。让我知道你的想法。

于 2013-01-16T03:14:37.343 回答