在extBoxSplitAmount中,我输入数字,例如12,这意味着我粘贴到richTextBoxToSplit中的文本应该被拆分成等于12个文本块.例如,如果我在文本框111111中输入,则它应该将文本划分为111111个相等的块.

我添加了一个名为lblSizeInfo的新标签,它显示richTextBoxToSplit中整个文本的大小,还显示每个块的大小,这取决于我在文本框中输入的块的数量,或者还取决于我粘贴到richTextBox中的文本的数量,在这两种情况下,它都在计算大小并显示它们.

例如,如果我将一个文本粘贴到richTextBox中,文本的大小是:481字节,每个块的大小是12,所以每个块的大小是72字节,但然后我在文本框中将块的数量更改为11111111,现在它显示每个块的大小为63.58MB,但这是不可能的,因为整个文本大小只有481字节.

我的计算逻辑中的错误在哪里?

calculation of size is wrong

我不知道在这种情况下该怎么办?首先,如何才能使计算正确?其次,我应该以某种方式避免用户输入像11111111这样的长数字吗?也许我应该限制文本可以划分的可能块的数量?

更新方法:

private void UpdateSplitButtonState()
{
    // Check if the text box is empty or contains only '0'
    bool isTextBoxEmptyOrZero = string.IsNullOrEmpty(textBoxSplitAmount.Text) || textBoxSplitAmount.Text.All(c => c == '0');

    // Check if the rich text box is empty
    bool isRichTextBoxEmpty = string.IsNullOrEmpty(richTextBoxToSplit.Text);

    // Enable the "Split" button only if both conditions are met
    btnSplit.Enabled = !(isTextBoxEmptyOrZero || isRichTextBoxEmpty);

    // Calculate and display size information
    if (!isRichTextBoxEmpty && !isTextBoxEmptyOrZero)
    {
        int textSizeInBytes = Encoding.UTF8.GetByteCount(richTextBoxToSplit.Text);
        int blockSize = int.Parse(textBoxSplitAmount.Text);

        if (blockSize > 0 && richTextBoxToSplit.Text.Length > 0)
        {
            long blockSizeInBytes = blockSize * Encoding.UTF8.GetMaxByteCount(1);
            lblSizeInfo.Text = FormatSizeInfo(textSizeInBytes) + ", Block Size: " + FormatSizeInfo(blockSizeInBytes);
        }
        else
        {
            lblSizeInfo.Text = "";
        }
    }
    else
    {
        lblSizeInfo.Text = ""; // Clear the label if the rich text box is empty or blockSize is zero
    }
}

和Format方法:

private string FormatSizeInfo(long sizeInBytes)
{
    const long KB = 1024;
    const long MB = 1024 * KB;
    const long GB = 1024 * MB;

    if (sizeInBytes >= GB)
    {
        double sizeInGB = (double)sizeInBytes / GB;
        return string.Format("{0:F2} GB", sizeInGB);
    }
    else if (sizeInBytes >= MB)
    {
        double sizeInMB = (double)sizeInBytes / MB;
        return string.Format("{0:F2} MB", sizeInMB);
    }
    else if (sizeInBytes >= KB)
    {
        double sizeInKB = (double)sizeInBytes / KB;
        return string.Format("{0:F2} KB", sizeInKB);
    }
    else
    {
        return string.Format("{0} bytes", sizeInBytes);
    }
}

Richtextobx TextChanged事件:

private void richTextBoxToSplit_TextChanged(object sender, EventArgs e)
{
    UpdateSplitButtonState();
}

ExtBoxSplitAmount TextChanged事件:

private void textBoxSplitAmount_TextChanged(object sender, EventArgs e)
{
    UpdateSplitButtonState();
}

按键:

private void textBoxSplitAmount_KeyPress(object sender, KeyPressEventArgs e)
{
    if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
    {
        e.Handled = true; // Ignore the key press if it's not a digit or a control character (e.g., Backspace)
    }
}

推荐答案

首先,如果您将481个字节划分为12个块,结果应该是40个字节,而不是72个字节,因此即使对于原始示例,您的逻辑也不起作用.

你的逻辑错误在方法UpdateSplitButtonState中,在这一行:

long blockSizeInBytes = blockSize * Encoding.UTF8.GetMaxByteCount(1);

你应该用总的字节数除以块的数量,但是你要用Encoding.UTF8.GetMaxByteCount(1)乘以blockSize,它总是1.Encoding.UTF8.GetMaxByteCount(1)在这里有什么作用?

更重要的是,您应该将变量blockSize重命名为amountOfBlocks.就目前而言,它非常具有误导性,因为如果我正确理解了您的问题,您在文本框中输入的值应该是块的数量,而不是每个块的大小.得到文本的长度(以字节为单位)和块的数量后,用除法计算每个块的大小(以字节为单位):

long blockSizeInBytes = textSizeInBytes / amountOfBlocks;

在条件块if (!isRichTextBoxEmpty && !isTextBoxEmptyOrZero){ }内,如下所示更新代码:

int textSizeInBytes = Encoding.UTF8.GetByteCount(richTextBoxToSplit.Text);
int amountOfBlocks = int.Parse(textBoxSplitAmount.Text);

if (amountOfBlocks > 0 && textSizeInBytes > 0)
    {
        long blockSizeInBytes = textSizeInBytes / amountOfBlocks;
        lblSizeInfo.Text = FormatSizeInfo(textSizeInBytes) + ", Block Size: " + FormatSizeInfo(blockSizeInBytes);
    }
    else
    {
        lblSizeInfo.Text = "";
    }
}

我是否应该以某种方式避免用户能够输入这么长时间 像11111111这样的数字?也许我应该限制可能的数量 文本可以分割到的块?

为了限制用户可以输入的块的数量,您需要考虑文本的实际长度.例如,如果长度是10个字符,那么块的最大数量将是10,但如果您的文本是1000个字符,那么您可以在文本框中输入多达1000个字符.

首先,在类Form1中,添加一个私有字段""previousAmount tOfBlock"",以便在更改之前的文本框值时跟踪它:

public partial class Form1 : Form
{
    private int previousAmountOfBlocks = 0;
    
    // the rest of the class code continues...
}

然后,再次更新条件if (!isRichTextBoxEmpty && !isTextBoxEmptyOrZero){ }内的逻辑,如下所示:

int textSizeInBytes = Encoding.UTF8.GetByteCount(richTextBoxToSplit.Text);
var amountOfBlocks = int.Parse(textBoxSplitAmount.Text);

if (amountOfBlocks > 0 && textSizeInBytes > 0)
{
    long blockSizeInBytes = textSizeInBytes / amountOfBlocks;

    // if the result of the division is < 1, the amount of blocks is
    // too large for the current text size so we set the
    // textbox value to the previous value and return
    if (blockSizeInBytes < 1)
    {
        textBoxSplitAmount.Text = previousAmountOfBlocks.ToString();
                   
        return;
    }

    lblSizeInfo.Text = FormatSizeInfo(textSizeInBytes) + ", Block Size: " + FormatSizeInfo(blockSizeInBytes);

    // update the previousAmountOfBlocks to the current, accepted value
    previousAmountOfBlocks = amountOfBlocks;
}

Csharp相关问答推荐

Microsoft.AspNetCore.Mvc. Controller Base.用户:属性或索引器Controller Base.用户无法分配给--它是只读的

获取ASP.NET核心身份认证cookie名称

如何使用ConcurentDictionary属性上的属性将自定义System.Text.Json JsonConverter应用于该属性的值?

是否可以使用EF—Core进行临时部分更新?

安装附加的. exe与Visual Studio

如果属性名为xyz,我需要使用System.Text.Json修改字符串类型的值""<>

在C#中使用类中的对象值

从应用程序图API调用访问所有者字段

Azure Redis缓存与Entra ID身份验证

将轮询与超时同步

在实体框架中处理通用实体&S变更跟踪器

Unix上的.NET(核心):.NET意外地未看到通过P/Invoke系统调用对环境变量进行的进程内修改

取决于您的数据量的多个嵌套循环

委托RequestDelegate不带2个参数-ASP.NET Core 8最小API

对于PowerShell中的ConvertTo-SecureString方法,Microsoft如何将初始化向量添加到AES加密中的安全字符串?

在使用StringBuilder时,如何根据 colored颜色 设置为richTextBox中的特定行着色?

如何从非异步任务中正确返回TypeResult

如何设置WinForms按钮焦点,使其看起来像是被Tab键插入其中?

为什么连接到Google OAuth2后,结果.Credential为空?

这是T自身的布尔表达式是什么意思?