已回答 在文本框中将多行合并为一行

已加入
2020年5月15日
留言内容
29
编程经验
Beginner
你好

我有一个wpf应用程序,该应用程序有一个文本框,使用扫描仪将值插入其中。一次扫描单个数据时,文本框中会出现多行,可以向下滚动以查看。但是我不希望它们是多行。我想将所有行合并为一行,并在文本框中查看而无需滚动。我怎样才能做到这一点。谢谢。
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,501
地点
悉尼,澳大利亚
编程经验
10+
Text属性是一个像其他字符串一样的String,因此您可以在换行符上将其拆分,然后以所需的任何方式组合结果数组,然后重新显示最终结果。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,925
地点
英国
编程经验
10+
什么 you are asking will very depending on the design of your elements and controls. In WPF, there are a few things you need to do to stop scrolling. First you should start off using : TextWrapping="NoWrap" - This only takes you so far, as now it will not breach and drop onto another line. It also won't stretch the control as the digits are appended. So the size of your control will decide the fate of how much of the text is displayed.

另外,您可能要添加: HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"
您应该有一些看起来像这样的xaml:
C#:
<TextBox Name="tbox1" Text="Test" VerticalContentAlignment="Center" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" TextWrapping="NoWrap" />

让我们知道这是您要做什么吗?
 
已加入
2020年5月15日
留言内容
29
编程经验
Beginner
What you are asking will very depending on the design of your elements and controls. In WPF, there are a few things you need to do to stop scrolling. First you should start off using : TextWrapping="NoWrap" - This only takes you so far, as now it will not breach and drop onto another line. It also won't stretch the control as the digits are appended. So the size of your control will decide the fate of how much of the text is displayed.

另外,您可能要添加: HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"
您应该有一些看起来像这样的xaml:
C#:
<TextBox Name="tbox1" Text="Test" VerticalContentAlignment="Center" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" TextWrapping="NoWrap" />

让我们知道这是您要做什么吗?

不,我还是不明白。我扫描了QR码,这就是我在文本框中看到的内容。
SAR41-d1A3
5701/014
每次转化费用
01.04.2020

但是我想要的是文本框中的SAR41-d1A35701 / 014Cpa01.04.2020。不幸的是,直到现在我还是无法理解。请帮我。
 
已加入
2020年5月15日
留言内容
29
编程经验
Beginner
What you are asking will very depending on the design of your elements and controls. In WPF, there are a few things you need to do to stop scrolling. First you should start off using : TextWrapping="NoWrap" - This only takes you so far, as now it will not breach and drop onto another line. It also won't stretch the control as the digits are appended. So the size of your control will decide the fate of how much of the text is displayed.

另外,您可能要添加: HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"
您应该有一些看起来像这样的xaml:
C#:
<TextBox Name="tbox1" Text="Test" VerticalContentAlignment="Center" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" TextWrapping="NoWrap" />

让我们知道这是您要做什么吗?
我也想告诉你,我正在为文本框使用按键按下事件,当我扫描QR码时,我一次获得的行数不相同,并且不是全部都在一起,这会导致按键按下处理程序出现问题,因为我认为插入每行时执行。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,925
地点
英国
编程经验
10+
向我显示您的keydown事件代码?

您可以使用 分裂 加入 在不换行的情况下重整文本。
 
已加入
2020年5月15日
留言内容
29
编程经验
Beginner
向我显示您的keydown事件代码?

您可以使用 分裂 加入 在不换行的情况下重整文本。

C#:
 private void Unio_mod2_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Return)
            {
                    string mod1_ctrl;
                    mod1_ctrl = unio_mod2.Text;
                    var ctrl = new Kontrolle_Scan();
                    // as you can see when I pass the mod1_ctrl to the other class
                    // then I want to pass it as single text with no spaces and as
                    // you can see mod1_ctrl gets its data from the  文本框  which is
                    // Unio_mod2.
                    ctrl.Auswertung_mod1(mod1_ctrl); // code for this can found below
                    var mod1_temp = ctrl.get_mod1_ctrl();
                
                    // rest is not important for you
                
                    //MessageBox.Show(mod1_temp.ToString());
                    int SK1count = ctrl.Karte1_existiert(mod1_ctrl);
                    //MessageBox.Show(SK1count.ToString());
                    //MessageBox.Show("Number of SK1 cards in UNIO DB is " + SK1count.ToString());
                    
                    if (SK1count != 0)
                    {
                        MessageBox.Show("Diese Signal Karte 1 wurde bereits in einem anderen UNIO-Modul verwendet");
                        unio_mod2.Text = "";
                    }
                    else
                    {
                        if (mod1_temp != 1 && mod1_temp != -1)
                        {
                            unio_mod2.Background = Brushes.Red;
                            const string caption = "Entscheidung akzeptiert.";
                            var result = System.Windows.Forms.MessageBox.Show(String.Format("Das eingescannte Modul ist nicht in den Datenbanken vorhanden. \nMöchten Sie das Modul trotzdem eintragen?"), caption, System.Windows.Forms.MessageBoxButtons.YesNo).ToString();

                            if (result == "No")
                            {
                                unio_mod2.Background = Brushes.White;
                                unio_mod2.Text = "";
                            }
                            else if (result == "Yes")
                            {
                                mod1_temp = 1;
                            }
                        }
                        
                        else if(mod1_temp == -1)
                        {
                            
                            unio_mod2.Text = "";
                            unio_mod2.Focus();                           
                        }
                        
                        else if (mod1_temp == 1)
                        {
                            if (unio_mod2.Text.Length >= 30 && unio_mod2.Text.Length <= 40 && unio_mod2.Text != unio_mod1.Text)
                            {
                                mod1 = unio_mod2.Text;
                                unio_mod2.Background = Brushes.Green;
                                unio_mod3.Focus();
                            }
                        }
  
              }

您可以从中了解到Unio_mod2是文本框。

Kontrelle Scan是一个不同的类,这是该代码。
//这部分也不重要。但是只是为了让您可以看到
C#:
public void Auswertung_mod1(string mod1_temp)
        {
            DataGridAdapter_4AI.Fill(ds._4AI);
            DataGridAdapter_4AO.Fill(ds._4AO);
            DataGridAdapter_2AI2AO.Fill(ds._2AI2AO);
            DataGridAdapter_PT100.Fill(ds.PT100);
            
            if (mod1_temp.Substring(0, 3)== "SAR"   ||   mod1_temp.Length<13)
            {
                MessageBox.Show("Sie haben den falschen Code gescannt. \nBitte scannen Sie den korrekten Datenmatrizencode");
                mod1 = -1;
            }
            else
            {
                string filter_mod1 = mod1_temp.Substring(13, 6);
                var temp1 = ds._4AI.Where(o => o.Herstellerseriennummer == filter_mod1).Count();
                var temp2 = ds._4AO.Where(o => o.Herstellerseriennummer == filter_mod1).Count();
                var temp3 = ds._2AI2AO.Where(o => o.Herstellerseriennummer == filter_mod1).Count();
                var temp4 = ds.PT100.Where(o => o.Herstellerseriennummer == filter_mod1).Count();
                mod1 = temp1 + temp2 + temp3 + temp4;
            }                 
        }

如您所见,代码有点复杂。此代码是较大程序的一部分。
 
已加入
2020年5月15日
留言内容
29
编程经验
Beginner
向我显示您的keydown事件代码?

您可以使用 分裂 加入 在不换行的情况下重整文本。
C#:
string[] lines = unio_mod2.Text.Split('\n');
MessageBox.Show(lines[0]);

我只是在keydown事件处理程序中使用了此代码。所以请记住,我告诉过您,扫描二维码的输出是
SAR41-d1A3
5701/014
每次转化费用
01.04.2020.

所以我希望这会发生
线[0] = SAR41-d1A3
行[1] = 5701/014
行[2] = 每次转化费用
线[3] = 01.04.2020

和SAR41-d1A3应该是必须显示的一个消息框。这就是我的期望。

但是消息框显示的是01.04.2020。我也看到另一个消息框的简短闪烁出现在该消息框之前。因此,我假设第一行存储在line [0]中,然后将其删除,第二行再次存储在line [0]中,依此类推,我们可以看到最后一行。所以这是我的主要问题。每行分别出现。
 
已加入
2020年5月15日
留言内容
29
编程经验
Beginner
向我显示您的keydown事件代码?

您可以使用 分裂 加入 在不换行的情况下重整文本。
我也想说上面的问题是当我设置AcceptsReturn ="False". When I set it to 真正 then multiline is allowed. Then the key down event handler is not working as I can just see the multiple line in the 文本框 and nothing else is happening.
 
已加入
2020年5月15日
留言内容
29
编程经验
Beginner
我创建了一个简单的程序,该程序具有一个texbox,可以接受来自扫描QR码的文本。这是文本框。

C#:
<TextBox x:Name="LearnTextBox" HorizontalAlignment="Left" Height="23" Margin="83,173,0,0" VerticalAlignment="Top" Width="620" Cursor="Pen" MaxLength="39"  接受 sReturn="True" KeyDown="LearnTextBox_KeyDown">
        </TextBox>

如您所见,我已经设置了AcceptsReturn ="True"这意味着允许多行。现在,对于实际代码,它甚至只是一个简单的按键。因此,当keydown事件发生时,来自文本框的文本将存储在字符串变量中,
然后使用消息框显示。

C#:
namespace LearnTextboxKeyDownEvent
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            LearnTextBox.Focus();
        }
        private void LearnTextBox_KeyDown(object sender, KeyEventArgs e)
        {
           
            if(e.Key == Key.Return)
            {
                string text = LearnTextBox.Text;              
                MessageBox.Show(text);
            }
        }
    }
}

现在的问题是,AcceptsReturn ="True"则不会发生LearnTextBox_KeyDown事件。没事AcceptsReturn ="False",则如果QR码给出一行文字,则按下事件有效。但是,如果是多行,则多个消息框一个接一个地出现,一秒钟后消失,因此可以看到发生的类似闪烁的事件。我想设置AcceptsReturn ="True"然后应该为此处理一个事件。如果不是按键按下事件,那么应该使用哪个事件。请帮我。
 
由主持人最后编辑:

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,500
地点
弗吉尼亚州切萨皮克
编程经验
10+
首先,我要假设让扫描仪作为键盘驱动程序运行的原因是因为您没有SDK可以直接访问扫描仪数据。因此,这意味着当您敲击扫描枪上的扳机时,就让它模仿了在键盘上的打字。如果这将是一个正在进行的项目,建议您与扫描仪的制造商联系,以查看是否可以最好地获得SDK的副本,或者可以更好地获得其Windows驱动程序的源代码的副本,然后获取数据。直接从扫描仪。

其次,您发现看到回车键时试图立即处理输入并不能满足您的需求。我建议使用另一种方法。像这样的伪代码:
C#:
// In view code:

public ScannerInputTextBox : TextBox
{

public event EventHandler DataReady;

ScannerInputTextBox()
    : base()
{
    :
    isWaitingForInput = true;
    timer = new DispatcherTimer();
    timer.Tick += (o,e) => FireDataReadyEvent();
    timer.Interval = TimeSpan.FromSeconds(1);     // wait for input to complete in 1 second
}

OnTextChange()
{
    if (!isWaitingForInput)
        return;

    // reset the timer to keep waiting
    timer.Stop();
    timer.Start();
}

FireDataReadyEvent()
{
    isWaitingForInput = false;
    timer.Stop();
    DataReady?.Invoke(...);
    isWaitingForInput = true;
}

}    // end of custom ScannerInputTextBox control

// In your view model code:

InputViewModel()
{
    scannerInputTextBox.DataReady += (o, e) => OnDataReady;
}

OnDataReady()
{
    var fourLineText = scannerInputTextBox.Text.Split('\n');
    var  加入 edText = string.Join("", fourLineText);
    scannerInputTextBox.Text =  加入 edText;
    
    // do rest of processing of  加入 edText to do your database queries, etc.
}

上面的伪代码所做的是假定您从文本框中派生一个类并添加一个新的DataReady事件。然后,自定义文本框等待文本更改事件并启动计时器。如果更多输入持续快速进入,则计时器复位。如果没有更多输入输入,则计时器到期,并引发DataReady事件。然后,在包含该自定义控件的页面代码中,您等待DataReady事件。触发时,您可以将4条线拆分和合并为一条线,并进行其余的数据处理。

顺便说一句,为什么要像编写WinForms代码一样编写WPF代码?
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,925
地点
英国
编程经验
10+
已加入
2020年5月15日
留言内容
29
编程经验
Beginner
首先,我要假设让扫描仪作为键盘驱动程序运行的原因是因为您没有SDK可以直接访问扫描仪数据。因此,这意味着当您敲击扫描枪上的扳机时,就让它模仿了在键盘上的打字。如果这将是一个正在进行的项目,建议您与扫描仪的制造商联系,以查看是否可以最好地获得SDK的副本,或者可以更好地获得其Windows驱动程序的源代码的副本,然后获取数据。直接从扫描仪。

其次,您发现看到回车键时试图立即处理输入并不能满足您的需求。我建议使用另一种方法。像这样的伪代码:
C#:
// In view code:

public ScannerInputTextBox : TextBox
{

public event EventHandler DataReady;

ScannerInputTextBox()
    : base()
{
    :
    isWaitingForInput = true;
    timer = new DispatcherTimer();
    timer.Tick += (o,e) => FireDataReadyEvent();
    timer.Interval = TimeSpan.FromSeconds(1);     // wait for input to complete in 1 second
}

OnTextChange()
{
    if (!isWaitingForInput)
        return;

    // reset the timer to keep waiting
    timer.Stop();
    timer.Start();
}

FireDataReadyEvent()
{
    isWaitingForInput = false;
    timer.Stop();
    DataReady?.Invoke(...);
    isWaitingForInput = true;
}

}    // end of custom ScannerInputTextBox control

// In your view model code:

InputViewModel()
{
    scannerInputTextBox.DataReady += (o, e) => OnDataReady;
}

OnDataReady()
{
    var fourLineText = scannerInputTextBox.Text.Split('\n');
    var  加入 edText = string.Join("", fourLineText);
    scannerInputTextBox.Text =  加入 edText;
   
    // do rest of processing of  加入 edText to do your database queries, etc.
}

上面的伪代码所做的是假定您从文本框中派生一个类并添加一个新的DataReady事件。然后,自定义文本框等待文本更改事件并启动计时器。如果更多输入持续快速进入,则计时器复位。如果没有更多输入输入,则计时器到期,并引发DataReady事件。然后,在包含该自定义控件的页面代码中,您等待DataReady事件。触发时,您可以将4条线拆分和合并为一条线,并进行其余的数据处理。

顺便说一句,为什么要像编写WinForms代码一样编写WPF代码?
谢谢。由于我只是C#和WPF的初学者,因此我将尝试实现这一点并在遇到任何查询时返回,如果可以肯定的话。
 
已加入
2020年5月15日
留言内容
29
编程经验
Beginner
首先,我要假设让扫描仪作为键盘驱动程序运行的原因是因为您没有SDK可以直接访问扫描仪数据。因此,这意味着当您敲击扫描枪上的扳机时,就让它模仿了在键盘上的打字。如果这将是一个正在进行的项目,建议您与扫描仪的制造商联系,以查看是否可以最好地获得SDK的副本,或者可以更好地获得其Windows驱动程序的源代码的副本,然后获取数据。直接从扫描仪。

其次,您发现看到回车键时试图立即处理输入并不能满足您的需求。我建议使用另一种方法。像这样的伪代码:
C#:
// In view code:

public ScannerInputTextBox : TextBox
{

public event EventHandler DataReady;

ScannerInputTextBox()
    : base()
{
    :
    isWaitingForInput = true;
    timer = new DispatcherTimer();
    timer.Tick += (o,e) => FireDataReadyEvent();
    timer.Interval = TimeSpan.FromSeconds(1);     // wait for input to complete in 1 second
}

OnTextChange()
{
    if (!isWaitingForInput)
        return;

    // reset the timer to keep waiting
    timer.Stop();
    timer.Start();
}

FireDataReadyEvent()
{
    isWaitingForInput = false;
    timer.Stop();
    DataReady?.Invoke(...);
    isWaitingForInput = true;
}

}    // end of custom ScannerInputTextBox control

// In your view model code:

InputViewModel()
{
    scannerInputTextBox.DataReady += (o, e) => OnDataReady;
}

OnDataReady()
{
    var fourLineText = scannerInputTextBox.Text.Split('\n');
    var  加入 edText = string.Join("", fourLineText);
    scannerInputTextBox.Text =  加入 edText;
   
    // do rest of processing of  加入 edText to do your database queries, etc.
}

上面的伪代码所做的是假定您从文本框中派生一个类并添加一个新的DataReady事件。然后,自定义文本框等待文本更改事件并启动计时器。如果更多输入持续快速进入,则计时器复位。如果没有更多输入输入,则计时器到期,并引发DataReady事件。然后,在包含该自定义控件的页面代码中,您等待DataReady事件。触发时,您可以将4条线拆分和合并为一条线,并进行其余的数据处理。

顺便说一句,为什么要像编写WinForms代码一样编写WPF代码?
你好

我正在尝试实现这一点。但是我对C#的了解仅限于c ++,java等中存在的基本编程。因此这些主题对我来说是新的。所以我必须学习它们以实现它们。您能否建议我要实现的所有知识或所学的知识。我一直在尝试搜索一个好的教程,该教程教您如何在线创建自定义文本框。但是我找不到它。所以,请让我知道我应该学习什么。谢谢。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,500
地点
弗吉尼亚州切萨皮克
编程经验
10+
在C ++和Java中,有继承的概念。这就是您要做的一切:从TextBox控件继承并添加自定义内容。
 
已加入
2020年5月15日
留言内容
29
编程经验
Beginner
在C ++和Java中,有继承的概念。这就是您要做的一切:从TextBox控件继承并添加自定义内容。
我确实了解继承,并且从您的伪代码中了解到,自定义文本框正在继承实际的文本框控件。但是我不知道诸如此类的工作方式。因为在c ++和java中,当您从类继承时,您仍然需要使用其自己的对象来调用新类。但是在这里我很困惑。运行程序时会发生什么。我运行程序,打开带有文本框的主窗口,当我按下扫描枪上的扳机并读取二维码时,将触发哪个文本框。主UI或自定义控件类中的一个。因此,我不知道这些事情,因此无法找到任何好的在线教程。
 
已加入
2020年5月15日
留言内容
29
编程经验
Beginner
在C ++和Java中,有继承的概念。这就是您要做的一切:从TextBox控件继承并添加自定义内容。
好吧,让我说对了。我必须完全了解自定义控件。这是它如何工作的。我使用文本框创建了一个不同的用户控件,并将具有添加功能的新文本框替换了现有控件。这是怎么工作的。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,500
地点
弗吉尼亚州切萨皮克
编程经验
10+
是。这是干净的方法。子类化文本框,并改用子类。

另一种方法是不子类化,而是将事件处理程序附加到文本更改事件上以执行相同的操作:触发计时器。每次更改计时器时重置一次。如果一段时间后没有更多更改,则将触发计时器滴答事件。在计时器滴答事件处理程序中,进行处理以合并行,然后进行数据库处理。
 
已加入
2020年5月15日
留言内容
29
编程经验
Beginner
是。这是干净的方法。子类化文本框,并改用子类。

另一种方法是不子类化,而是将事件处理程序附加到文本更改事件上以执行相同的操作:触发计时器。每次更改计时器时重置一次。如果一段时间后没有更多更改,则将触发计时器滴答事件。在计时器滴答事件处理程序中,进行处理以合并行,然后进行数据库处理。
好的,谢谢,我刚开始学习自定义控件,就是在我得到创意并将其发布到上面时。好的,在我擅长创建自定义文本框之前,我还有很多东西要学习。
 
最佳 底部