【问题标题】:How would I combine multiple methods in to one method我如何将多种方法组合成一种方法
【发布时间】:2017-05-12 15:07:31
【问题描述】:

我有 15 个字段几乎做同样的事情:

    private void TextboxMessage1_TextChanged(object sender, TextChangedEventArgs e)
    {
      SaveMessage(TextboxMessage1.Text, TextboxMessageSeconds1.Text.ToInteger(), 1);
    }

    private void TextboxMessage2_TextChanged(object sender, TextChangedEventArgs e)
    {
      SaveMessage(TextboxMessage2.Text, TextboxMessageSeconds2.Text.ToInteger(), 2);
    }

    private void TextboxMessage3_TextChanged(object sender, TextChangedEventArgs e)
    {
      SaveMessage(TextboxMessage3.Text, TextboxMessageSeconds3.Text.ToInteger(), 3);
    }

etc

调用SaveMessage:

private void SaveMessage(string textboxMessageText, int seconds, int messagenumber)
{
  var msg = _configman.MyConfig.MessageConfigs.FirstOrDefault(x => x.MessageNumber == messagenumber);

  if (msg == null)
  {
    var msgconfig = new MessageConfig();
    msgconfig.Seconds = seconds;
    msgconfig.Command = textboxMessageText;
  }
  else
  {
    msg.MessageNumber = messagenumber;
    msg.Command = textboxMessageText;
    msg.Seconds = seconds;
  }
  _configman.SaveConfig();
}

我的表格:

<CheckBox x:Name="CheckBoxMessage1" Content="" HorizontalAlignment="Left" Margin="29,23,0,0" VerticalAlignment="Top" Width="15"/>
<TextBox x:Name="TextboxMessage1" Height="23" Margin="49,19,158,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" TextChanged="TextboxMessage1_TextChanged"/>
<Button x:Name="ButtonMessage1" Content="Disabled" HorizontalAlignment="Left" Margin="689,20,0,0" VerticalAlignment="Top" Width="75" Background="#FFFB8686" Click="ButtonMessage1_Click"/>
<CheckBox x:Name="CheckBoxMessage2" Content="" HorizontalAlignment="Left" Margin="29,48,0,0" VerticalAlignment="Top" Width="15"/>
<TextBox x:Name="TextboxMessage2" Height="23" Margin="49,44,158,0" TextWrapping="Wrap" VerticalAlignment="Top" TextChanged="TextboxMessage2_TextChanged"/>
<Button x:Name="ButtonMessage2" Content="Disabled" HorizontalAlignment="Left" Margin="689,45,0,0" VerticalAlignment="Top" Width="75" Background="#FFFB8686"/>
<CheckBox x:Name="CheckBoxMessage3" Content="" HorizontalAlignment="Left" Margin="29,72,0,0" VerticalAlignment="Top" Width="15"/>
<TextBox x:Name="TextboxMessage3" Height="23" Margin="49,68,158,0" TextWrapping="Wrap" VerticalAlignment="Top" TextChanged="TextboxMessage3_TextChanged"/>
<Button x:Name="ButtonMessage3" Content="Disabled" HorizontalAlignment="Left" Margin="689,69,0,0" VerticalAlignment="Top" Width="75" Background="#FFFB8686"/>

有没有办法让 TextChanged 覆盖我所有的文本框,这样我就不必为每个文本框创建 TextChanged 了?

它们编号为 1-15,例如 TextboxMessage1、TextboxMessage1 等。

这可能吗?如果是这样,我该怎么做?

【问题讨论】:

  • 这就是人们使用 MVVM 的原因。使用 MVVM,这种事情变得非常简单。如果您学习 MVVM 并学习适当的 XAML 技术(如 StackPanel 和网格布局以及样式),您的生活将变得更加轻松,您的代码也将变得更加简单和易读。您应该有一个由 ItemsControl 实例化十五次的 UserControl 或 DataTemplate。但这有点学习曲线,如果你离重新开始的路太远,下面的两个答案都有很好的想法。

标签: c# xaml controls


【解决方案1】:

为什么不对每个 TextChanged 事件使用相同的“通用”回调,例如“TextboxMessage_TextChanged”。 那么:

<TextBox x:Name="TextboxMessage1" Height="23" Margin="49,19,158,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" TextChanged="TextboxMessage_TextChanged"/>

private void TextboxMessage_TextChanged(object sender, TextChangedEventArgs e)
{
  TextBox tb = sender as TextBox;
  int index = int.Parse(tb.Name.Substring("TextboxMessage".Length));
  TextBox secondTextBox = (TextBox)this.FindName("TextboxMessageSeconds" + index);
  SaveMessage(tb.Text, secondTextBox.Text.ToInteger(), index);
}

这是你所期待的吗?

【讨论】:

    【解决方案2】:

    最好的方法是使用继承自 TextBoxint 属性创建一个新类

    //Come up with a better name
    public class CustomTextBox : TextBox
    {
        public int Number { get; set; }
    }
    

    然后在您的 xaml 中将属性类型更改为 CustomTextBox(或您命名的任何名称)。确保添加Number 属性并将TextChanged 属性更改为“TextBoxSave_TextChanged”:

    <CustomTextBox x:Name="TextboxMessage1" Height="23" Margin="49,19,158,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" TextChanged="TextBoxSave_TextChanged" Number="1"/>
    

    然后在你的代码后面添加一个新方法TextBoxSave_TextChanged()

    //You can name it whatever, I would keep the "_TextChanged" suffix though
    private void TextBoxSave_TextChanged(object sender, TextChangedEventArgs e)
    {
        //Cast sender to your new CustomTextBox type
        CustomTextBox txtBox = ((CustomTextBox)sender);
    
        SaveMessage(txtBox.Text, txtBox.Text.ToInteger(), txtBox.Number);
    }
    

    艾德的建议:

    public class CustomTextBox : TextBox
    {
        #region Number Property
        public int Number
        {
            get { return (int)GetValue(NumberProperty); }
            set { SetValue(NumberProperty, value); }
        }
    
        public static readonly DependencyProperty NumberProperty =
            DependencyProperty.Register(nameof(Number), typeof(int), typeof(CustomTextBox),
                new PropertyMetadata(0));
        #endregion Number Property
    
        #region Seconds Property
        public int Seconds
        {
            get { return (int)GetValue(SecondsProperty); }
            set { SetValue(SecondsProperty, value); }
        }
    
        public static readonly DependencyProperty SecondsProperty =
            DependencyProperty.Register(nameof(Seconds), typeof(int), typeof(CustomTextBox),
                new PropertyMetadata(0));
        #endregion Seconds Property
    }
    

    TextChanged 处理程序:

    //  You can name it whatever, I would keep the "_TextChanged" suffix though
    private void TextBoxSave_TextChanged(object sender, TextChangedEventArgs e)
    {
        //Cast sender to your new CustomTextBox type
        CustomTextBox txtBox = (CustomTextBox)sender;
    
        SaveMessage(txtBox.Text, txtBox.Seconds, txtBox.Number);
    }
    

    XAML 用法:

    <local:CustomTextBox 
        Number="1"
        Seconds="{Binding Text, ElementName=TextboxMessageSeconds1}"
        TextChanged="TextBoxSave_TextChanged" 
    
        x:Name="TextboxMessage1" 
        Height="23" 
        Margin="49,19,158,0" 
        TextWrapping="Wrap"
        VerticalAlignment="Top" 
        />
    

    但实际上,这是编写适当的 UserControl 的糟糕替代品。

    【讨论】:

    • 感谢您的回复,但我仍然需要创建 15 个,因为“3”必须是硬编码的,除非我遗漏了什么?
    • 我错过了 int 的不同之处。给我一秒钟编辑
    • 刚刚进行了更新,允许您访问控件的新属性。
    • @maccettura SaveMessage() 的第二个参数是解析来自不同控件的文本(TextMessageSecondsN 与 TextMessage),因此 CustomTextBox 还需要一个依赖属性,以便他可以使用 ElementName 绑定到另一个控件。或者他可以从 Gizmo 的答案中窃取 FindName 代码。
    • @maccettura 好吧,他还不如坚持使用 Gonzo 建议的糟糕(但比原来的糟糕得多!)代码。您介意我将依赖属性的代码附加到您的答案中吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-11
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    相关资源
    最近更新 更多