简体   繁体   中英

How to make a 'variable' method name in C#?

I'm new to C# programming, have a little bit of background in C/C++. I'm trying to write a problem, like an equalizer almost, just playing with code. Imagine 5 vertical sliders next to each other, and when you move the middle slider up and down, the other sliders react with a specific value, based on a hash function I'll figure out at a later date, at the moment I have simple equations.

However, when I add more sliders, I don't want to go through and add a function for every single slider, so is there a way to 'detect' which slider is moving, and send it through an algorithm to move the the adjacent sliders? Basically, I'd like one function to move the adjacent sliders to any slider I choose to move. Logically, it makes sense, however I don't know how to do it in code.

The function that I've written for a specific slider is below.

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;
    }

I may have not explained it fully, feel free to ask questions!

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

When you need the adjacent sliders, build a List of the sliders in FormLoad. You can then find the index of thisSlider and work from there.

Edit: I'm not sure if WPF triggers the events when changing values in code. If it does you may need this to prevent it from going into a loop:

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;
}

I didn't use C# and Visual Studio for a while, so I can't remember if there is a direct way to use arrays in the window designer, someone should clear that in the comments ;).

But what you probably want is to Instead of declaring slider1, slider2, slider3, ... you should use an array so that you can access slider[0], slider[1], ...

For this you firstly must change the design of the form to use an array and then access this array in your handler.

without array:

        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;

with array:

        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;
        }

Then you can access all track bars via trackBar[x]. You can change the 3 in the declaration and for loop to a constant you want or to a variable.

you can also do it in xaml only. You just need a FormulaCalculationConverter . I tried it and it works well.

<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>

and I just created a converter like

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();
   }
}

But you need to work on converter for this. Let me know your thoughts.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM