This is a migrated thread and some comments may be shown as answers.

Databinding in LINQ vs OpenAccess different in same/similar code

8 Answers 118 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Adam
Top achievements
Rank 1
Adam asked on 31 Jul 2009, 09:36 PM
I am really confused with how to DataBind. I have 2 nearly identical projects, one using LINQ, the other OpenAccess, using only the Categories table from the Northwind database. Basically, a grid (of that table), and 2 textboxes for editing / 2-way binding.

Here is the code for Window1.xaml (LINQ Project):
<Window x:Class="NWLinq.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:NWLinq" 
    Title="Northwind LINQ" Height="400" Width="575" xmlns:my="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView"
    <Window.Resources> 
        <ObjectDataProvider x:Key="objectDataProvider" ObjectType="{x:Type local:TestViewModel}"  /> 
    </Window.Resources> 
 
    <Grid DataContext="{Binding Source={StaticResource objectDataProvider}}"
        <Grid.ColumnDefinitions> 
            <ColumnDefinition Width="200*" /> 
            <ColumnDefinition Width="300*" /> 
        </Grid.ColumnDefinitions> 
        <Grid.RowDefinitions> 
            <RowDefinition Height="60*" /> 
            <RowDefinition Height="60*" /> 
            <RowDefinition Height="240*" /> 
        </Grid.RowDefinitions> 
        <my:RadGridView  
            Grid.Row="2"  
            Name="radGridView1"  
            Grid.ColumnSpan="2"  
            ColumnsWidthMode="Fill" 
            IsReadOnly="False"  
            SelectedItem="{Binding SelectedItem}" 
            ItemsSource="{Binding CategoryList}"              
        > 
        </my:RadGridView> 
        <TextBlock Margin="91,16,41,10" Name="textBlock1" Text="Name" HorizontalAlignment="Right" VerticalAlignment="Center" /> 
        <TextBlock Margin="91,14,41,8" Name="textBlock2" Grid.Row="1" Text="Description" HorizontalAlignment="Right" VerticalAlignment="Center" /> 
        <TextBox Grid.Column="1" Margin="58,15,64,11" Name="textBox1" Text="{Binding Path=SelectedItem.CategoryName, Mode=TwoWay}"  /> 
        <TextBox Margin="58,14,64,8" Name="textBox2" Grid.Column="1" Grid.Row="1" Text="{Binding Path=SelectedItem.Description, Mode=TwoWay}"  /> 
    </Grid> 
</Window> 
 

and from the OA project:
<Window x:Class="NWOA.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:my="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView"     
    xmlns:local="clr-namespace:NWOA" 
    Title="Northwind OpenAccess" Height="400" Width="575" > 
    <Window.Resources> 
        <ObjectDataProvider x:Key="objectDataProvider" ObjectType="{x:Type local:TestViewModel}"  /> 
    </Window.Resources> 
 
    <Grid DataContext="{Binding Source={StaticResource objectDataProvider}}"
        <Grid.ColumnDefinitions> 
            <ColumnDefinition Width="200*" /> 
            <ColumnDefinition Width="300*" /> 
        </Grid.ColumnDefinitions> 
        <Grid.RowDefinitions> 
            <RowDefinition Height="60*" /> 
            <RowDefinition Height="60*" /> 
            <RowDefinition Height="240*" /> 
        </Grid.RowDefinitions> 
        <my:RadGridView  
            Grid.Row="2"  
            Name="radGridView1"  
            Grid.ColumnSpan="2"  
            ColumnsWidthMode="Fill" 
            IsReadOnly="False"  
            SelectedItem="{Binding SelectedItem}" 
            ItemsSource="{Binding CategoryList}"              
        > 
        </my:RadGridView> 
        <TextBlock Margin="91,16,41,10" Name="textBlock1" Text="Name" HorizontalAlignment="Right" VerticalAlignment="Center" /> 
        <TextBlock Margin="91,14,41,8" Name="textBlock2" Grid.Row="1" Text="Description" HorizontalAlignment="Right" VerticalAlignment="Center" /> 
        <TextBox Grid.Column="1" Margin="58,15,64,11" Name="textBox1" Text="{Binding Path=SelectedItem.CategoryName, Mode=TwoWay}"  /> 
        <TextBox Margin="58,14,64,8" Name="textBox2" Grid.Column="1" Grid.Row="1" Text="{Binding Path=SelectedItem.Description, Mode=TwoWay}"  /> 
    </Grid> 
</Window> 
 

They should be identical (other than x:Class=...)

The Window1.xaml.cs files are the same (except for the namespace:
using System.Windows; 
 
namespace NWLinq 
    public partial class Window1 : Window 
    { 
        public Window1() 
        { 
            InitializeComponent(); 
        } 
    } 
------- 
 
using System.Windows; 
 
namespace NWOA 
    public partial class Window1 : Window 
    { 
        public Window1() 
        { 
            InitializeComponent(); 
        } 
    } 
 

The viewmodels are as close as can be, based on different requirements for LINQ and OA:
using System.Collections.Generic; 
using System.Linq; 
 
namespace NWLinq 
    public class TestViewModel 
    { 
        NWLinqDataContext dc = new NWLinqDataContext(); 
        public TestViewModel() 
        { 
            SetTable(); 
        } 
 
        public void SetTable() 
        { 
            var query = 
            from c in dc.Categories select c; 
            CategoryList = query.ToList(); ; 
        } 
 
        public IList<Category> CategoryList 
        { 
            get
            set
        } 
 
        public Category SelectedItem 
        { 
            get
            set
        } 
 
    } 
 

using System.Collections.Generic; 
using NWOpenAccess; 
using Telerik.OpenAccess; 
using Telerik.OpenAccess.Query; 
 
namespace NWOA 
    public class TestViewModel 
    { 
        private IObjectScope scope = NWScopeProvider.GetNewObjectScope(); 
        public TestViewModel() 
        { 
            SetTable(); 
        } 
 
        public void SetTable() 
        { 
            var query = 
            from c in this.scope.Extent<Category>() select c; 
            CategoryList = query.ToList(); ; 
        } 
 
        public IList<Category> CategoryList 
        { 
            get
            set
        } 
 
        public Category SelectedItem 
        { 
            get
            set
        } 
 
    } 
 

I won't paste the code for the LINQ designer or the OA designer. Basically, just use the Categories table. From Northwind.

On the grid, moving up and down, the textboxes are updated in both apps.

The problem: If I edit in the grid, the changes are reflected in the textbox for the LINQ program and NOT the OA program.

What am I missing?


A follow up question... what is the best way to save the changes back to the database, and when? When the user moves off the record? When a button is pressed to confirm?












8 Answers, 1 is accepted

Sort by
0
Nedyalko Nikolov
Telerik team
answered on 06 Aug 2009, 11:45 AM
Hi Adam,

In order to enable data update with Telerik Open Access you have to make it with a transaction. The easiest way for WPF/Silverlight is to implement IEditableObject for generated from Open Access class.
I'm attaching a running example based on your code for your reference.

Hope this helps.

P.S. Be aware that this will update underlying data source not like "Linq to SQL" way that updates only objects in memory.

Kind regards,
Nedyalko Nikolov
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Adam
Top achievements
Rank 1
answered on 07 Aug 2009, 03:47 AM
I used your sample code and it worked, but it won't solve my issue of the SQL2008 new data types. Will LINQ work for this?

Also, I made a minor change, and it does not display data in the grid. It is obviously something SIMPLE I am overlooking, because the data appears in the textboxes.

<my:RadGridView Grid.Row="2" Name="radGridView1" Grid.ColumnSpan="2" ColumnsWidthMode="Fill" AutoGenerateColumns="False" 
                        IsReadOnly="False" SelectedItem="{Binding SelectedItem}"  
                        ItemsSource="{Binding CategoryList}"
            <my:RadGridView.Columns> 
                <my:GridViewColumn Header="A Name" UniqueName="CategoryName" /> 
                <my:GridViewColumn Header="A Description" UniqueName="Description" /> 
            </my:RadGridView.Columns> 
        </my:RadGridView> 

AutoGenerateColumns="False"
and added 2 columns

All the documentation I find talks about DataMember which does not exist.


0
Adam
Top achievements
Rank 1
answered on 07 Aug 2009, 03:50 AM
I meant to say DataMemberPath

Error    1    The property 'DataMemberPath' does not exist in XML namespace 'clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView'. Line 25 Position 78.    D:\Data\Projects\Samples\NWOA\Window1.xaml    25    78    NWOA

0
Adam
Top achievements
Rank 1
answered on 08 Aug 2009, 02:53 AM
Well, I figured out where the DataMemberPath is... GridViewDataColumn. I was using GridViewColumn.

How would I know... ?

When I click on the Collections editor for Columns, the only choice is GridViewColumn. What is the trick for setting this?

Another odd behavior is when I edit a cell, tab to the next cell (from Name to Description) and hit tab again (to go to the next record, Name), EndEdit is not called. In fact, you can hold down the Tab key and cycle through the whole thing several times and it won't trigger EndEdit. I did not see where EndEdit is set in the XAML, so how is this triggered and how can you activate it on leaving the row?

When the commit occurs, it does not save to the database. What is required to save the data to the database?
0
Adam
Top achievements
Rank 1
answered on 08 Aug 2009, 05:38 AM
Apparently, it does not save in debug mode...

However, I have another couple of issues.
If I run 2 release versions of this program, and make changes in 1, it is not reflected in the other nor does it warn that the record was changed when the 2nd application goes to edit that same record. What is the best way to

1) warn user 2 that the record was changed
2) refresh the grid

 
0
Nedyalko Nikolov
Telerik team
answered on 10 Aug 2009, 10:39 AM
Hello Adam,

Generally you should use DataMemberBinding instead of DataMemberPath property.
You can use GridViewColumn as unbound column (for example place a button in every GridViewRow or something like that). Unfortunately RadGridView.Columns collection is a collection of GridViewColumns as this a base class for all columns classes.

About how to commit data there are two events CellEditEnded and RowEditEnded which depends on ValidationMode (default value is Cell and RowEditEnded will not fire). It's up to you how you will commit data to the data source (LINQ to SQL will not do this for you). Also you can use custom logic using BeginningEdit and EditEnded events to prevent an object from editing while it is edited in another application (or another computer).

Best wishes,
Nedyalko Nikolov
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Adam
Top achievements
Rank 1
answered on 10 Aug 2009, 11:43 AM
Pardon my ignorance, being new to C# / WPF, how would I, from the Visual Studio designer (or Blend), drop a grid on a form and do what you are suggesting?

Could you explain how, for example, to drop a grid on a form for Northwind and have it show all the products, perhaps just a few fields so that autogenerated colums is false, so that the category id (and/or supplierid) is a dropdown / combobox to select from the other table.

How would I set the DataMemberBInding?

Can this be done through the designer, or do you have to go into the code?
How can you tell if a record is being edited elsewhere?

Since LINQ to SQL does not do the saving, would OpenAccess be better? How would I do record locking or determine if the row was edited elsewhere?

Thanks in advance, really confused.
0
Nedyalko Nikolov
Telerik team
answered on 13 Aug 2009, 11:07 AM
Hi Adam,

Unfortunately Visual Studio designer is not as usable for WPF as it is for WinForms. My personal choice is to edit xaml (Visual Studio has very good intellisense) or code behind directly. So with VS2008 better way is to edit xaml to add DataMemberBinding. Expression Blend is a little bit better for setting properties at design time, but still this cannot be done only with mouse.

I can suggest you to take a closer look at our online examples (source code and xaml is included) on how to add columns and set some properties. About editing there are several events that you can use in order to meet your goals no matter of the chosen data source (Linq to SQL or OpenAccess).

Kind regards,
Nedyalko Nikolov
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
Tags
GridView
Asked by
Adam
Top achievements
Rank 1
Answers by
Nedyalko Nikolov
Telerik team
Adam
Top achievements
Rank 1
Share this question
or