UWP TextBox.SelectedText changes \\r\\n to \\r

2019-02-24 06:09发布

问题:

I need to get the characters that preceed a TextBox's SelectedText, but I can't get the SelectionStart to match up with the TextBoxes' Text properties, apparently because TextBox's SelectedText scrubs \n values.

I have a Windows 10 UWP application. I've added two TextBoxes and one Button, as represented by the XAML below:

<StackPanel>
    <Rectangle Height="40"></Rectangle><!-- quicker than turning off debug numbers -->
    <TextBox Height="300" Name="textBox" AcceptsReturn="True" />
    <Button Click="Button_Click" Content="Selection" ></Button>
    <TextBox Height="100" Name="textBox2" AcceptsReturn="True" />
</StackPanel>

I've initialized the Page by putting some text into the first TextBox.

    public MainPage()
    {
        this.InitializeComponent();
    }

    private void Page_Loaded(object sender, RoutedEventArgs e)
    {
            this.textBox.Text = @"Call me Ishmael. Some years ago--never mind how long precisely--having little
or no money in my purse, and nothing particular to interest me on shore, I
thought I would sail about a little and see the watery part of the world. It is
a way I have of driving off the spleen and regulating the circulation. Whenever
I find myself growing grim about the mouth; whenever it is a damp, drizzly
November in my soul; whenever I find myself involuntarily pausing before coffin
warehouses, and bringing up the rear of every funeral I meet; and especially
whenever my hypos get such an upper hand of me, that it requires a strong moral
principle to prevent me from deliberately stepping into the street, and
methodically knocking people's hats off--then, I account it high time to get to
sea as soon as I can.";
    }

I would've expected something like the following would get what's selected (again, I don't need SelectedText; I need the previous characters, but I'm grabbing what's selected here to make things easier to follow):

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        textBox2.Text = textBox.Text.Substring(textBox.SelectionStart,
            20 < textBox.SelectionLength ? 20 : textBox.SelectionLength);
    }

That doesn't. It strangely seems to get SelectionStart based on a value for textBox.Text that doesn't include \n. Here's what I mean...

If I highlight the first two lines...

Call me Ishmael. Some years ago--never mind how long precisely--having little or no money in my purse, and nothing particular to interest me on shore, I

... things work, and I get back what I'd expect ("Call me Ishmael. Som"). But with each drop down a line, I get one more character than I'd expect. So lines 2 & 3 give a newline first (\n extra):

If we jump ahead to lines 4 and 5 (so we're skipping three lines), I get three characters back before the selection.

That is, selecting this...

a way I have of driving off the spleen and regulating the circulation. Whenever I find myself growing grim about the mouth; whenever it is a damp, drizzly

... gives this...

s\r\n
a way I have of d

(Note: I've highlighted what was selected manually here, just to help visualize what's going on.)

If I check SelectedText, every newline is reduced to a \r, so this almost makes sense, except that textBox.Text still has platform appropriate \r\n's instead!

That is, if I put a breakpoint in the Button_Click event, and check textBox.SelectedText, I get...

"a way I have of driving off the spleen and regulating the circulation. Whenever\rI find myself growing grim about the mouth; whenever it is a damp, drizzly\r"

See the \r only? Yet textBox.Text gives...

"Call me Ishmael. Some years ago--never mind how long precisely--having little\r\nor no money in my purse, and nothing particular to interest me on shore, I\r\n[...]"

If I want to get what I'd expect, I can do something silly like...

    public static string NormalizeNewlineToCarriageReturn(this string str)
    {
        str = str.Replace("\r\n", "\r");
        str = str.Replace("\n", "\r");
        return str;
    }

And then...

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        textBox2.Text = textBox.Text.NormalizeNewlineToCarriageReturn().Substring(textBox.SelectionStart,
            20 < textBox.SelectionLength ? 20 : textBox.SelectionLength);
    }

But that's crazy. And if TextBox ever starts working like I'd expect, that breaks.

What's going on? I mean, I see explanations (like this from Mr. Skeet) that seem to shortcircuit to "You need to use NewLine" to explain missing \n's in TextBoxes, but in UWP, at least, I think it's more complicated than that.

标签: c# textbox uwp