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

OpenAccess and WPF DataBinding with conditions

6 Answers 166 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
rent
Top achievements
Rank 1
rent asked on 06 Jan 2010, 08:29 PM
Hello ALL!!!
I want to make a project such in example http://www.telerik.com/help/openaccess-orm/openaccess-tasks-howto-binding-wpf.html
but in my project I have this situation:
I have MS SQL Database named NCHTEC and 1 table OBJECTS:
CREATE TABLE [dbo].[OBJECTS]( 
    [OBJECT_ID] [intNOT NULL
    [OBJECT_NAME] [nvarchar](50) COLLATE Cyrillic_General_CI_AS NOT NULL
    [OBJECT_STATE] [bitNOT NULL
 CONSTRAINT [PK_OBJECTS_1] PRIMARY KEY CLUSTERED  
    [OBJECT_ID] ASC 
)WITH (IGNORE_DUP_KEY = OFFON [PRIMARY
ON [PRIMARY]
And I want to have in WPF page many controls such as Polyline or TextBoxes with unique names and its names in my NCHTEC too and I want to bind values from fleld OBJECT_ID to every controls in page. How to realize this?
Sources is http://ifolder.ru/15815818 or http://rapidshare.com/files/331640727/NCHTEC.rar
Thanks in advance!!


6 Answers, 1 is accepted

Sort by
0
rent
Top achievements
Rank 1
answered on 09 Jan 2010, 07:23 AM
Anybody can help me?
0
Jordan
Telerik team
answered on 11 Jan 2010, 04:31 PM
Hello rent,

The issue is that the converter returns an IQueryable and not a single value.
I changed the Convert method like in the sample bellow and it seems to be working fine:
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
       {
           IQueryable<DBObject> table = (IQueryable<DBObject>)value;
           //return table.Where("ObjectId=1").Select("ObjectId");
           return table.Where(o => o.ObjectId == 1).Select(o => o.ObjectId).First();
       }

I hope this helps. Do not hesitate to write again if you have more questions or suggestions.

Best wishes,
Jordan
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
rent
Top achievements
Rank 1
answered on 11 Jan 2010, 05:37 PM

Thank you very much  Jordan !!!

But it is not complete: in my situation need to realize ConvertBack in IConverter and save changes to database knowing the fact of that changed ID with his state need to update in database... and in Convert and in ConvertBack seems to be use converter parameter to  save Polilyne or Polygon id .....What about this?

P.S. Unfortunatelly гnfortunately i give one more problem:

When I set in XAML binding mode TwoWay I give the error: Xaml parse exception: for two way binding need Path or XPath? BUT in this situation it is not applicable... There is any way to solve this problem?

Thanks in advance!!

0
Jordan
Telerik team
answered on 14 Jan 2010, 01:01 PM
Hi rent,

Indeed, in WPF you cannot have two way binding without specifying a Path. This is needed so that the WPF binding functionality knows where to save to.

Anyway, I found a simpler way that does not involve converters and will allow you to use much simpler binding expressions like in the sample bellow:
<TextBox Height="23" Margin="52,30,106,0" x:Name="textBox1" VerticalAlignment="Top" Background="MediumTurquoise" Text="{Binding Path=ObjectState}">

In order for this to work I have change the code for the window like bellow:
private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            context = NCHTECDataProvider.GetNewObjectScope();
            IQueryable<DBObject> query = context.Extent<DBObject>();
            FrameworkElement[] boundElements = new FrameworkElement[] { this.textBox1 };
            foreach (FrameworkElement element in boundElements)
            {
                DBObject value = query.Where(o => o.ObjectName == element.Name).FirstOrDefault();
                if (value != null)
                {
                    element.DataContext = value;
                }
            }
 
            context.TransactionProperties.AutomaticBegin = true;
        }
 
        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            base.OnClosing(e);
            context.Transaction.Commit();
        }
there are three important things to notice in the above snippet:
1. in order specify which elements you want to data bind you change the boundElements array
2. you must set the <scope>.TransactionProperties.AutomaticBegin property to true
3. in order to save the changes call <scope>.Transaction.Commit()

I hope this helps.

Best wishes,
Jordan
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
rent
Top achievements
Rank 1
answered on 29 Jan 2010, 07:51 AM

Thank you very much Jordan!!! Useful solution!

I've tested and find a make bug (???):

When I run my WPF application in text box named textBox1 i change text from 0 to 1 but in database this changes comes after second try. Why? I have added textBox1 TextChanged event and in this event write following code:

context.Transaction.Commit();   
Thanks in advance!!!!

0
Jordan
Telerik team
answered on 01 Feb 2010, 10:10 AM
Hi rent,

What you have noticed  is most probably the result from the default source update behavior for the TextBox being LostFocus. This means that the source of the binding is updated only after the text box loses focus, i.e. the user  has to give focus to some other control before closing the form (and calling commit).

Of course there is the option of changing the UpdateSourceTrigger to PropertyChanged, which will cause the source property to be updated on every change.

I suggest that you look at this MSDN article so that you can make an informed decision:
http://msdn.microsoft.com/en-us/library/ms752347.aspx#what_triggers_source_updates

Also if you want to update the database not only when the form closes you must commit the current transaction (if there is one) like in the sample bellow:
if (context.Transaction.IsActive)
            {
                context.Transaction.Commit();
            }

I hope this helps.

Kind regards,
Jordan
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Tags
General Discussions
Asked by
rent
Top achievements
Rank 1
Answers by
rent
Top achievements
Rank 1
Jordan
Telerik team
Share this question
or