New Posts New Posts RSS Feed: Navigation Properties and Data Binding
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Navigation Properties and Data Binding

 Post Reply Post Reply
Author
tj62 View Drop Down
Groupie
Groupie
Avatar

Joined: 21-May-2009
Location: Iceland
Posts: 81
Post Options Post Options   Quote tj62 Quote  Post ReplyReply Direct Link To This Post Topic: Navigation Properties and Data Binding
    Posted: 14-Jan-2011 at 3:28am

Hi,

Hi,

I have noticed a "bug" or something when using navigation properties with data-binding. Let me take a practical example. It is pretty long, but very simple.

 

I have an entity EntOpcGroup with an navigtion property EntDevice.

In a dataform (actually an AtomForm http://akashkava.com/blog/) I present EntOpcGroup but also EntDevice.p_name. So I was going to do a lazy load of EntDeivce only when the user requested each EntOpcGroup. First I did this such, and it worked 100%:

 

XAML databinding:

<ns:AtomForm x:Name="c_DeviceForm"

   DataContext="{Binding p_currentItem, Mode=TwoWay}"             

....

<ns:AtomTextBox x:Name="c_deviceType"

   Text="{Binding p_vm.p_deviceName, Source={StaticResource ViewModelLocator}, Mode=OneWay}"

....

 

View Model code:

        #region Device lazy loading and bound property for Device Type Name

        /// <summary>

        /// Performs lazy loading of Device when an EntOpcGroup is selected

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)

        {

            if (e.PropertyName == "p_currentItem")

            {

                var entOpcGroup = (EntOpcGroup)p_currentItem;

                if (entOpcGroup.p_device.EntityAspect.IsPendingEntity)

                    // The device has not been loaded from database. Ask for lazy loading and set event handler

                    entOpcGroup.p_device.EntityAspect.PendingEntityResolved += OnPendingEntDeviceResolved;

                else

                    // The device is already loaded, notify the bound XAML text box.

                    RaisePropertyChanged("p_deviceName");

 

            }

        }

 

        /// <summary>

        /// The devuce is received from the database with the lazy load triggerd in OnPropertyChanged.

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void OnPendingEntDeviceResolved(object sender, PendingEntityResolvedEventArgs e)

        {

            RaisePropertyChanged("p_deviceName");

            ((Entity)sender).EntityAspect.PendingEntityResolved -= OnPendingEntDeviceResolved;

        }

 

        public string p_deviceName

        {

            get

            {

                if (p_currentItem == null)

                    return null;

                return ((EntOpcGroup)p_currentItem).p_device.p_name;

            }

        }

        #endregion

 

Then I wanted to eliminate the p_deviceName property that is actualy outside the p_currentItem that is bound to the form. So I did those changes:

 

XAML:

<ns:AtomForm x:Name="c_DeviceForm"

   DataContext="{Binding p_currentItem, Mode=TwoWay}"             

....

<ns:AtomTextBox x:Name="c_deviceType"

    Text="{Binding p_deviceName, Mode=OneWay}"

....

 

 View Model code:

        #region Device lazy loading and bound property for Device Type Name

        /// <summary>

        /// Performs lazy loading of Device when an EntOpcGroup  is selected

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)

        {

            if (e.PropertyName == "p_currentItem")

            {

                var entOpcGroup = (EntOpcGroup)p_currentItem;

                if (entOpcGroup.p_device.EntityAspect.IsPendingEntity)

                    // The device has not been loaded from database. Ask for lazy loading and set event handler

                    entOpcGroup.p_device.EntityAspect.PendingEntityResolved += OnPendingEntDeviceResolved;

 

            }

        }

 

        /// <summary>

        /// The device is received from the database with the lazy load triggerd in OnPropertyChanged.

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void OnPendingEntDeviceResolved(object sender, PendingEntityResolvedEventArgs e)

        {

            RaisePropertyChanged("p_deviceName");

            ((Entity)sender).EntityAspect.PendingEntityResolved -= OnPendingEntDeviceResolved;

        }

 

 

And then I define p_deviceName in EntOpcGroup such:

    public partial class EntOpcGroup

    {

        /// <summary>

        /// Added for binding convenience

        /// </summary>

        public string p_deviceName2 {get{return p_device.p_name;}}

    }

 

Now when I run this code it does not work properly (but almost). The strange thing is that when OnPendingEntDeviceResolved is triggered, IsPendingEntity=false as expected but there is no data in the EntDevice instance (the “sender” parameter) an it is still Detatched. However if I select another instance of EntOpcGroup and back to the first again then the EntDevice.p_name is displayed correctly in the form. When I investigate that time in the debugger the EntDevice instance has data and is no more Detatched.


So it seems like the OnPendingEntDeviceResolved happens “a little bit too eraly”.

The only code difference is actually the binding. That is to say in the first case I bind to an “external” property in the view model. But in the later case I bind directly to a added property in EntOpcGroup.
This is probably a bug or what?!?!

 

Back to Top
DenisK View Drop Down
IdeaBlade
IdeaBlade


Joined: 25-Aug-2010
Posts: 715
Post Options Post Options   Quote DenisK Quote  Post ReplyReply Direct Link To This Post Posted: 14-Jan-2011 at 5:20pm
Hi tj62;

I'm not really an expert in data binding or AtomForm but I'd like to comment on one thing and hopefully it can help you figure things out.

Regarding your statement,

"The strange thing is that when OnPendingEntDeviceResolved is triggered, IsPendingEntity=false as expected but there is no data in the EntDevice instance (the “sender” parameter) an it is still Detatched"

IsPendingEntity=false when (PendingEntityResolvedEventArgs) e.ResolvedEntity != null.

The "sender" parameter does not necessarily indicate the pending entity.

Could you check if e.ResolvedEntity has the pending entity that you want everytime OnPendingEntDeviceResolved is triggered regardless if the "sender" is detached or not?
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down