13

So, for example if I have 2 text boxes in WFA. The following code works.

private void textBox1_TextChanged(object sender, EventArgs e)
    {
        textBox2.Text = textBox1.Text;
    }

And I get this. The text in the second text box equals to the text in the first one, when I change it. enter image description here

But when it comes to WPF, I get a completely different behavior. When I do this.

private void textBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        textBox1.Text = textBox.Text;
    }

And press Ctrl+F5 to test the application, nothing happens. The log says "Build Succeeded" and nothing. What is wrong here?

And here is the XAML code.

    <Window x:Class="TextBoxTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:TextBoxTest"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="212,77,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" TextChanged="textBox_TextChanged"/>
    <TextBox x:Name="textBox1" HorizontalAlignment="Left" Height="23" Margin="212,124,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>

</Grid>

Roman
  • 1,267
  • 2
  • 13
  • 20
  • 2
    Can you show your XAML for `TextBox` too? – Salah Akbari Nov 08 '15 at 19:13
  • 1
    This code works for me. It must be problem with Your XAML code. I created x:Name="textBox1" for first Text Box property and x:Name="textBox2" for the second one. – miechooy Nov 08 '15 at 19:18
  • Where do I add the XAML code? It says it's too long for a comment. – Roman Nov 08 '15 at 19:44
  • 1
    @Rooxie .. you can edit your question. – Salah Akbari Nov 08 '15 at 19:46
  • @Rooxie...Try clean and rebuild your solution may helpful. – Salah Akbari Nov 08 '15 at 19:53
  • What do you mean by nothing happens? The app does not run or the text does not change when you type in to the first text box? – Praveen Paulose Nov 08 '15 at 19:54
  • The app does not run. It's just says that the build was successful and then nothing. If I delete the code "textBox1.Text = textBox.Text;" the app starts. Tried it three times, creating a new project every time. Perhaps something wrong with my Visual Studio? – Roman Nov 08 '15 at 20:01
  • Try remove the X: before the name, for example: Name="MyTextBox", do this in both textboxes. – Bruno Joaquim Nov 08 '15 at 20:08
  • Just tried it, but the problem hasn't gone. I guess I'll try to reinstall Visual Studio first. – Roman Nov 08 '15 at 20:28
  • I reinstalled the Visual Studio and still nothing. Any ideas? Maybe something wrong with the OS? By the way I'm using Windows 10 x64, Visual Studio Community 2015. – Roman Nov 08 '15 at 21:28

2 Answers2

17

You are encountering a null reference exception. When the textBox control is created it will trigger the textChange event on textBox1 and by that point, textBox1 isn't created and is therefore null. You can just change the order of the textboxes in the XAML and you will be fine. But there is a nicer way of doing this, directly in XAML with Binding:

<TextBox x:Name="textBox" />
<TextBox x:Name="textBox1" Text="{Binding ElementName=textBox, Path=Text}" />

(I excluded some attributes to make the example more clean) Depending on WHEN you want the other textbox to update you can add UpdateSourceTrigger to the binding:

Text="{Binding ElementName=textBox, Path=Text, UpdateSourceTrigger=PropertyChanged}"
BDL
  • 21,052
  • 22
  • 49
  • 55
ceciliaSHARP
  • 1,000
  • 5
  • 14
  • 1
    Thanks for the reply. I just tried it, still didn't help me, but... The whole reason of my problem is that I'm and idiot. The problem was that the default text value of textBox was "TextBox" and because of it the program couldn't start, despite there were no errors. – Roman Nov 09 '15 at 18:08
14

And one more very fundamental reason is that you need to be cleared and understanding that in WPF practically ultimate goal is less Code-Behind coding with the View will be better, the actual practice is we all used the Binding way tend to do it in a much more cleaner manner, and fulfill the keys Maintainability, Testability, and Extensibility. We don't like the old-fashioned way of like the normal application implemented pattern. And you against this concept.

in your MainWindow.xaml.cs (Code-Behind) [Old Way]

private void textBox1_TextChanged(object sender, EventArgs e)
{
    textBox2.Text = textBox1.Text;
}

private void textBox_TextChanged(object sender, TextChangedEventArgs e)
{
    textBox1.Text = textBox.Text;
}

in your MainWindow.xaml (View) [Old Way]

<Window x:Class="TextBoxTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:TextBoxTest"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="212,77,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" TextChanged="textBox_TextChanged"/>
    <TextBox x:Name="textBox1" HorizontalAlignment="Left" Height="23" Margin="212,124,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
</Grid>

As of answered by ceciliaSHARP & edited by BDL

in your MainWindow.xaml.cs (Code-Behind) [WPF Way]

[Say no no and bye bye to the TextChangedEvent]

in your MainWindow.xaml (View) [WPF Way]

<Window x:Class="TextBoxTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:TextBoxTest"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="212,77,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" />
        <TextBox x:Name="textBox1" HorizontalAlignment="Left" Height="23" Margin="212,124,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="{Binding ElementName=textBox, Path=Text}" />
    </Grid>
</Window>

or the second option (WPF MVVM way with no "instantly changing event occurred")

in the MainWindow.xaml (View) slightly changed from the above part.

    <TextBox HorizontalAlignment="Left" Height="23" Margin="212,77,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="{Binding Path=Text, Mode=TwoWay}" />
    <TextBox HorizontalAlignment="Left" Height="23" Margin="212,124,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="{Binding Path=Text, Mode=TwoWay}" />

add new piece of Model code SomeModelName.cs

using System.ComponentModel;

public class SomeModelName : INotifyPropertyChanged
{

    private string text;

    public string Text
    {
        set
        {
            if (text != value)
            {
                text = value;
                RaisePropertyChanged("Text");
            }
        }
    }

    // some other properties and methods might go here
    // ...

    public event PropertyChangedEventHandler PropertyChanged;

    public void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

or the third option (WPF MVVM way with "instantly changing event occurred"), using the UpdateSourceTrigger

in the MainWindow.xaml (View) slightly changed from the above part.

    <TextBox HorizontalAlignment="Left" Height="23" Margin="212,77,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="{Binding Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
    <TextBox HorizontalAlignment="Left" Height="23" Margin="212,124,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="{Binding Path=Text, Mode=TwoWay}" />

I hoped this could make you and me myself understandable. It's all up-to-you to defined your own textbox behaviors...

Kong CY
  • 153
  • 1
  • 5