Question

I am new to C#. I want to resolve a data binding problem. The problem is this:

I defined a data binding for a text box in XAML part like the following ;

 <Window x:Class="WpfAppl2_DB_Entity.MainWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:l="clr-namespace:WpfAppl2_DB_Entity"
         Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
     <Window.Resources>
        <l:Emp x:Key="myEmp"/>
     </Window.Resources>
     <Grid Name="grid1">
         <TextBox Height="18" HorizontalAlignment="Left" Margin="229,94,0,0"
                 Name="textBox1" VerticalAlignment="Top" Width="96"  >
             <TextBox.Text>
                 <Binding Source="{StaticResource myEmp}" Path="empno" Mode = "TwoWay">
                     <Binding.ValidationRules>
                         <ExceptionValidationRule/>
                     </Binding.ValidationRules>
                 </Binding>
             </TextBox.Text>
         </TextBox>    
         <!-- more text boxes come here -->
     </Grid>
</Window>

Here the project's main namespace is "WpfAppl2_DB_Entity", to which I gave prefix "l", and then I defined a static resource "myEmp" which is an object of "Emp" class, Emp class is also defined in the same project and in same namespace, this is an entity class mapped to a table "emp" in database. I then bound the TextBox "textBox1" to the "empno" property of "myEmp" object. (I hope everything is clear to reader so far). There are 4 more text boxes on the form, which are bound to 4 other properties of Emp.

I defined a button on the main windows (content="Find", purpose is to find a record in emp table that has empno = value in texbox1). In the "Find" button's click event I wrote this:

            emps = amirDB.GetTable<Emp>();  // amirDB is an instance of a class  derived from DataContext class
            Emp qryEmp = new Emp();
            qryEmp = this.Resources["myEmp"] as Emp;
            var empQuery = from o in emps
                          where o.empno == Convert.ToInt32(textBox1.Text)
                         select o;
            foreach (Emp rec in empQuery)
            {
                qryEmp = new Emp();
                qryEmp.empno = rec.empno;
                qryEmp.ename = rec.ename;
                qryEmp.job = rec.job;
                qryEmp.sal = rec.sal;
                qryEmp.deptno = rec.deptno;
                break;   // we want to retrieve at most one record
            }

Now since the text boxes are bound to different properties of the static resource "myEmp" and we created a new Emp object "qryEmp", and then assigned the static resource to this new object (qryEmp = this.Resources["myEmp"] as Emp;). So, it means the 2 variables are referencing to the same object in memory(right?), after that I am assigning different properties of the retrieved record to corresponding properties of qryEmp object. So qryEmp now has the complete record that was retrieved from DB. Since myEmp is also pointing to same object, it should also have the record. And since the text boxes are bound to myEmp object, I was guessing that the text boxes should be updated to show the complete record data(all fields). But I see that the text boxes remain blank (only the first one has the value that was entered by keyboard).

My question is why the text boxes don't show the retrieved record values?

In an alternate way, I assign rec.* field values directly to text boxes in the above foreach loop (textBox2.Text=rec.ename, textBox3=rec.job, ....), in which case the text boxes show all the values as expected.

I wanted the code to assign front end/back end field values without referring to text boxes, because Microsoft claims that wpf separates the UI from business logic. So, my approach was to just bind all the text boxes to appropriate properties of an object, and then in programming logic, I use only the program objects (myEmp, qryEmp), no UI objects.

Can anybody help please? letting me know what am I doing wrong here? Thanks in advance.

No correct solution

OTHER TIPS

You're creating too many Emp instances.

Replace

Emp qryEmp = new Emp();
qryEmp = this.Resources["myEmp"] as Emp;

by

Emp qryEmp = this.Resources["myEmp"] as Emp;

and

foreach (Emp rec in empQuery)
{
    qryEmp = new Emp();
    qryEmp.empno = rec.empno;
    ...
}

by

foreach (Emp rec in empQuery)
{
    qryEmp.empno = rec.empno;
    ...
}

And make sure that

  • Emp implements the INotifyPropertyChanged interface,
  • empno etc. are public properties (not fields) in the Emp class,
  • and that these properties raise the PropertyChanged event.

You may also want to replace the foreach (Emp rec in empQuery) loop by

Emp rec in empQuery.FirstOrDefault();
if (rec != null)
{
    qryEmp.empno = rec.empno;
    ...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top