【问题标题】:How to use method(s) to add multiple, changing values如何使用方法添加多个变化的值
【发布时间】:2011-11-26 01:15:38
【问题描述】:

我正在为一个朋友做一个个人项目,但遇到了一些障碍。我可以照原样继续写一些真正多余的代码,但我觉得必须有更有效的方法来做到这一点。

我正在尝试编写一个方法,该方法将添加三个值并将结果显示到“技能修饰符”标题下的文本框中(参见屏幕截图)。我需要获得方法或一系列方法来为每个技能做到这一点。需要获取平衡、攀爬、脱逃等技能修正值...

方法类似于“CalculateSM”

我目前拥有的:

        private void btnUpdate_Click(object sender, EventArgs e)
    {
        //AM + R + MM =SM
        //AM = Ability Modifier
        //R = Rank
        //MM = Misc Modifier
        //SM = Skill Modifier

        decimal balanceMod = balanceAM.Value + balanceR.Value + balanceMM.Value;
        balanceSM.Text = balanceMod.ToString();

        decimal climbMod = climbAM.Value + climbR.Value + climbMM.Value;
        climbSM.Text = climbMod.ToString();

        //etc...
    }

对我来说,基本上最大的问题是弄清楚如何设计一种方法来处理这么多不同的字段名称并以相同的方式添加它们。我想避免为每项技能复制和粘贴相同的两行代码五十次。

任何想法将不胜感激!谢谢。

【问题讨论】:

    标签: c# winforms methods field


    【解决方案1】:

    使用这样的字段不是非常面向对象的。您可能会想要引入一个 Skills 类,该类实现计算最终技能分数的方法,然后使用一些 Skills 对象来获得不同的技能。

    public class Skill
    {
        int ability, rank, misc;
    
        public Skill(int ability, int rank, int misc)
        {
            this.ability = ability;
            this.rank = rank;
            this.misc = misc;
        }
    
        public int Score { get { return ability + rank + misc; }
    }
    
    Skill balance = new Skill(10, 1, 1);
    textBalance.Text = balance.Score.ToString();
    
    Skill programming = new Skill(10, 100, 0);
    textProgramming.Text = programming.Score.ToString();
    

    另外,想一个巧妙的方法将技能与您的用户控件联系起来。你不会喜欢以 50 个文本框结尾的,除了名字有点像之外。例如,第一步可能是将它们全部连接到同一个事件处理程序。

    【讨论】:

      【解决方案2】:

      通常,方法是创建一个代表技能屏幕的一行的类。然后,您可以以某种方式保留这些列表(例如,List<Skill>)。然后你可以很容易地遍历所有这些:

      foreach (Skill skill in character.Skills)
      {
           // do something with the skill object
      }
      

      诀窍是动态生成用户界面。做到这一点实际上并不难(虽然这里的代码太多了),到目前为止,最简单的方法是使用类似DataGridView 的东西。谷歌搜索示例应该相当容易,或者只是询问您是否需要特定信息。

      【讨论】:

      • +1。如果您想保留当前的 ​​UI,您可以创建一个代表一行的自定义用户控件。但是使用 DataGridView 更简单。
      • 是的,我一直在争论是否要提供更多有关这方面的信息,但我认为每天一次范式转换对于 OP 来说可能已经足够麻烦了 :)
      • 感谢您的回答。我一直在玩 DaraGridView 并且不完全确定您将如何使用列表来填充网格?我假设我想添加一个对象(列表?)作为数据源?我还发现控件也有些限制,但这没什么大不了的。此外,@Meta,有关范例 #2(自定义用户控件)的更多信息可能更适合我的需求。从我目前所读到的内容来看,至少可以说……很有用。 :P
      • @SarahMac - 也许 DataGridView 的建议也不是最好的,我正在寻找一种快速的方法来让您获得结果,而无需跳过箍。要回答您的问题,您通常会使用 BindingSource 对象,并将其 DataSource 设置为您的技能类的类型(在 VS 中可视化)。网格起初可能会受到限制,但一段时间后实际上会非常灵活。如果你走数据绑定路线,INotifyPropertyChanged 接口是非常需要的。
      • 就用户控制而言,是的,这是一个很好的方法。现在的额外复杂性是动态创建它们并为列表中的每个对象添加它们。您可能希望有一个像 FlowLayoutPanel 这样的容器,其 FlowDirection 设置为 TopDown,然后只需为每个技能对象实例化您的 UserControl,将技能作为参数传递给 UserControl,然后将 UserControl 添加到FlowLayoutPanel 的控件集合。这是一个速成课程,希望对您有所帮助。
      【解决方案3】:

      看起来您有一个对象集合,您可以将其数据绑定到 UI 中的某些东西(如数据网格或其他东西)

      修改值计算的东西,你可以在一些示例代码中做什么:

      class Skill
      {
          public string Name { get; set; }
          public string KeyAbility { get; set; }
          public int SkillModifier { get; set; }
          public int AbilityModifier { get; set; }
          public int Ranks { get; set; }
          public int MiscModifier { get; set; }
      
          void Calculate()
          {
              //Formula goes here
              //Set the SkillModifier
          }
      }
      
      Skill balance = new Skill() { Name = "Balance" }
      

      基本上,您可以收集技能,通过绑定到的任何 UI 对象进行更新等。像 atm 那样使用字段是非常多余的,而使用 OO 可以用更少的工作实现相同的目标。

      基本上你会创建一个技能类的集合,其中包含平衡和你提到的所有其他技能。将此集合数据绑定到 UI 中的某些内容,允许更新,调用不同的方法。你甚至可以为不同类型的技能实现一些继承。具有技能基类。

      【讨论】:

        【解决方案4】:

        balanceAM、balanceR等是什么类型?

        它们不能派生自可用于传递给辅助方法的基类型或接口吗?

            private string GetText(IModel modelAM, IModel modelR, IModel modelMM)
        {
          return  modelAM.Value + modelR.Value + modelMM.Value;
        }
        
        balanceSM.Text = this.GetText(balanceAM, balanceR, balanceMM);
        

        【讨论】:

          【解决方案5】:

          好的,每个单独的控件只有私有字段这一事实是您的核心问题。您最好创建一个结构列表来存储它们:

          struct PickYourOwnNameHere
          {
            Control SM;
            Control AM;
            Control R;
            Control MM;
          }
          
          List<PickYourOwnNameHere> skills = new List<PickYourOwnNameHere>();
          

          显然,在初始化时填充该列表,然后您就可以这样做:

          skills.ForEach(skill =>
              skill.SM.Text = (skill.AM.Value + skill.R.Value + skill.MM.Value).ToString()
          );
          

          我是凭记忆做那个语法的,但希望你能明白。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-04-24
            • 2019-02-02
            • 2011-09-08
            • 2020-12-20
            • 2020-12-03
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多