I have a complex object hierarchy that I've been wrestling with to get passed across the wire in its entirety when using Silverlight with WCF. I've tried DataContractSerializer to death and the main problem is that I'm trying to use Dictionary, with multiple cyclical references and just couldn't get it to work.
I've switched to look at protobuf-net thinking that it might be better all round to use a binary format anyway. I was hoping to be able to just do a lot of find and replace to add the ProtoMember attributes on to the properties. However a lot of the properties that were being serialized with DataMember attributes are declared as Friend (vb.net). I've found that protobuf-net throws an error when deserializing, saying
Attempt by method <blah> to access field <fieldname> failed.
I've found that setting the field to protected causes the same error, and the only way around it is to set the field to public - which is something I don't want to do. Is it possible to do this with a protected setter or similar on the property the field backs? While this would be a pain (many fields/properties and classes) it would at least solve the problem. The serialization on the back end works fine.
If this is not possible, can anyone suggest how I can get a complex object hierarchy with cyclical references that include multiple dictionaries across the wire in their complete form? I realise Silverlight adds a few constraints to this process, but hopefully someone has already succeeded with this.
Note this is Silverlight 5
In Silverlight: no; the runtime has a higher level of paranoia, and you just can't get at the non-public parts of other types. Even the Silverlight DataContractSerializer page has the caveat:
You can serialize fields and properties, provided they are publicly accessible.
My understanding is that this can't be avoided on Silverlight.
Related
I've just upgraded an old .NET 1.1 Winforms app that uses CSLA to .NET 4.0 and a later version of CSLA which supports the use of the INotifyPropertyChanged interface.
A large part of the reason for doing this is the databinding improves - e.g. being able to update on change when binding instead of when validating (tabbing off).
I have custom user control, NumberBox. Essentially it's just a textbox with a few properties such number type, decimal places etc.. I have exposed a public property of type object called BindableValue. It was this property that I was binding my CSLA classes (standard .NET classes inheriting validation rules, property changed and various stuff) integer property to, in this particular case it the class property is integer.
My problem having upgraded are the following:
If I enter a value, e.g. 1234, into my number box control it doesn't push the value back into the class' property it is bound to until I tab off, even though I have configured an object binding source to the custom BindableValue property with the update mode set to Property change.
Having entered value as in (1) if I go back and delete the value I am then prevented from tabbing off or clicking off the number box. I have set VS2010 to throw when .NET exception is thrown but it's not breaking.
It's been a while since I did WinForms stuff so I'm at a bit of a loss where to start. Any tips as well as a solution would be much appreciated.
EDIT:
I've tried a number of different things and am getting nowhere fast, it's getting really frustrating now:
I followed the info on MSDN, i.e. I added a ComplexBindingProperties attrib, slightly different in the textbox's private keyUp event handler I raise the event as indicated by the linked article OnBindableValueChanged(). However in all cases my event BindableValueChanged is always null.
I read similar articles to (1) but instead of declaring the event using EventHandler they used PropertyChangedEventHandler, tried this same result.
I added the DefaultBindingProperty attrib.
[You can read about this experience on my companies blog too - OCC Blog - Binding woes ]
I finally figured it out so thought I'd share it here to save someone else the tedium of trawling through Google reading lots of responses that say they work but in .NET 4.0 no longer seem to apply.
Okay, a lot of stuff I was reading on Google kept telling me my usercontrol had to have a Changed event using either EventHandler or PropertyChangedEventHandler delegates - different pages indicated different delegate. I tried both - fail!
What I had to do in .NET 4.0 is actually much nicer. Simply put just like my class that I was binding my usercontrol to does I had to implement the INotifyPropertyChanged interface. Then in my usercontrol when I wanted to pushback into my source object I just raised the PropertyChanged event (e.g. PropertyChanged("BindableValue"); ) the interface defined and hey presto all was well with the world again.
This above is a lot more elegant but unfortunately articles, forums and posts that are indexed by Google have not caught up with this yet for .NET 4.0 so all the existing stuff will lead you down dead ends and much frustration. I hope this saves someone else a lot of time.
Background:
I'm using MEF to help compose an Excel 2007 Add-In (VSTO) that can create an entity from spreadsheet data and a creep requirement exposed a shortcoming in my architecture that I'm trying to reconcile(I am now needing to identify columns on "template load" rather than on "worksheet submit")
I have each of my local entity properties decorated with a DescriptionAttribute that contains the name of the column in my worksheet. On submit, I reflect on these attributes to identify which property maps to that worksheet column and create a Dictionary of pairs that map a PropertyName to a column ordinal. I do this because the Excel COM object model seems to only expose the cells of a worksheet based upon row/column ordinals. Performing this mapping allows my add-in to dynamically locate my properties on the worksheet without having to maintain any static property-to-ordinal map.
So, this was all fine and good...and, as this is a stopgap solution for our business partner while we rearchitect the underlying system, we discussed that this was going to be a very "unfriendly" add-in and everyone was intitially onboard. But now, the business has validation concerns for some reference data that will be showing up in the sheet. We had agreed that validation would be performed on submission, but that has changed to need me to have reference columns bound to validation drop downs that only contain valid values.
The Problem
So now, I've been needing to restructure my View and ViewModel such that the mapping of the columns to their entity properties occurs on loading of the View, and that's where the problems have started. I implemented Josh Smith's RelayCommand from code that he has made available, I implemented Reed Copsey Jr's CompositionInitializer for WPF, and I created a ViewModelLocator to assist my compositioncontainer in locating my ViewModel...but whatever I do, I cannot locate the appropriate ViewModel. I'm a bit strung out on this issue at the moment..spent all weekend trying to fix it, to no avail. Can anyone please help? I'm not a MEF expert. I've dabbled with the MVVM pattern, but I've been outside of C# for the past few years and missed much of its evolution. I think it's highly likely that my problem is fundamental, but I have been staring at my code for too long to find it. Please, help.
The Code
I have begun a post in the Microsoft social forum for WPF where I have already posted the relevant code. If anyone would like me to repost it here, I would be happy to oblige. But for now, I will include a link to that thread. (I included a background in that thread as well, but I'm happier with the one here. You can skip the background I included over there and not miss anything)
http://social.msdn.microsoft.com/Forums/en/wpf/thread/f22f081d-e342-4f4e-af41-600cec68f0cd
I am uncertain whether this will have any impact, but instead of exporting your StopgapViewModel class, create a factory class and export the factory class, like so:
public StopgapViewModelFactory
{
[Export(typeof(StopgapViewModel))]
public StopgapViewModel Instance
{
get
{
return new StopgapViewModel();
}
}
}
Remove the [Export] declaration from the StopgapViewModel class, and give it a go.
Advance apologies for the event-style explanation; there's a lot of factors that I feel all play a role of their own. WPF is not my native framework of choice, and it probably shows. :)
Old situation: I had a window with several controls. Depending on their selections, I used multibindings and a converter to determine whether certain controls needed to be shown that inform the user about the implications of their changes before they'd eventually confirm them by OK (or simply dismissed by using Cancel). This worked perfectly.
Problem: Too many controls as time went by, too much clutter.
Solution: Put stuff in different Pages so it becomes easier to browse for the user. In order to have changes-to-be persist as a user arbitrarily browses between the pages, I create these dynamically and put them in a cache (Dictionary<string, BasePage>, see below), from which they will be pulled as the user chooses them.
Consequence: I need to decouple the bindings to the notification controls as the different options are now on different pages.
Solution? I put a BasePage class in that exposes certain abstract read-only properties that define the various aspects that the window needs to know about in order to do its notifications. For example, a bool requiresReboot property defines whether the current state of things on that page requires a reboot to take (full) effect. A specific page implements the property based on its controls.
Problem: I do not know how to keep create a proper binding that properly gets updated as the pages are changed. I tried giving my notification controls a binding to the Dictionary<string, BasePage> with a converter that checks all pages and the relevant property.
Questions:
1) How do I create a proper property for this purpose? I presume I need a DependancyProperty as I did a fair bit of reading on MSDN, but I can't figure out how this fits together.
2) How do I make a link between my custom property so that it allows (multiple) control(s) on a page to change that property? Do I use INotifyPropertyChanged somehow? My old example bound against several CheckBox.IsChecked properties in XAML. I am trying to avoid putting tons of events (OnChange, etc) on the controls as the original code did not need it and I have been told it makes for a messy solution for as far WPF is concerned.
3) Finally, I suspect I may need to change my Dictionary<string, BasePage> class to a custom implementation that implements some sort of INotifyPropertyChanged but for Collections? Observable Collection is the term I am looking for, I believe.
I hope someone is able to bridge the gap in my understanding of WPF (property) internals; I would very much appreciate it. A basic sample would be even better, but if it is too complicated, just a nudge in the right direction will do. Thank you. :)
It's been a while since I solved this, and while I cannot remember the exact cause of the problems, there were a few different issues that made up the bulk of the trouble I ran into.
I ended up making the Property in question a non-abstract DependencyProperty in the base class; it was the only way in which I could properly delegate the change notifications to the interface. Derived classes simply ended up binding it to their controls (with a proper Converter in the case extra logic was necessitated).
As Dictionary<string, BasePage> does not support any sort of change notification, I made an extra collection of ObservableCollection<BasePage> which I used for binding purposes.
However, such a collection does not propagate a change event when items inside of it has a property changed. Since this situation required that, and I was binding to the collection itself in the context of a property that does not have a Master<->Detail relationship like a DataGrid (which basically add their own OnPropertyChanged handlers to the binded object), I ended up subclassing a VeryObservableCollecton<>. This one listens to its own items, and throws a proper change event (I think it was an OnPropertyChanged from the INotifyPropertyChanged interface) so that the binding (or in this case a multi-binding) would refresh properly and allow my interface to update.
It is hardly the prettiest code, and it feels over-engineered, but at least it allows me to properly bind the UI to the data in this manner.
I just wasted invested a good chunk of time trying to determine why a specific datagrid among many was showing shrunken rows with no text. After many trial and errors attempts to figure out what made this grid special, I finally found that the class used for the row items was marked private.
That is a perfectly good reason, but I would have prefered to have been able to narrow it down to a binding issue (and if possible a "field is not accessable due to protection level" type message) much sooner then it took to sysmatically disassemble the entire convoluted process it took to get data into and configure that grid. Ideally I shouldn't have had to see the wrong behavoir in the first place, an error should have occured immediately when a column attempted to read from a field that it could not.
All my datagrids inherit from a custom base class in order for some global standards to be applied - if there anything I can do in my CustomDataGrid class to cause an exception to be thrown whenever a columns binding expression fails, such as if the class/property is private or the property name has been mispelled in the binding expression? (This is different from binding validation).
I always keep an eye out on debug output window when dealing with SL/WPF databinding. The framework(s) are actually pretty good at generating messages about databinding problems that include specific details about what fields it failed to bind on or what have you.
This doesn't exactly answer your original question, but it helped me sort through binding issues quite a bit once I realized there was good info being thrown into there.
This question is fairly straightforward -- I am trying to debug a memory leak in a silverlight application using s.o.s. I was able to get some good info using !gcroot to determine what objects have open references to the one that should be getting cleared; but in these cases they tend to be core UI elements (like grid and storyboard), and I can't really differentiate them without the ability to see the values of their dependency properties (like name). Trying to look through the dependency properties with !dumpobj is a total wild goose chase for me, they are all static classes (the properties that is) that reference each other and I just end up going in circles. At no point was I ever able to find a single actual value for a dependency property anywhere.
I googled about this quite a bit, but was only able to find other people asking the question, or speculation not leading to an answer. http://blogs.msdn.com/tess/archive/2008/09/16/q-a-reader-emails-about-net-memory-leaks-and-random-questions.aspx is one such page without answer.
Looking at the source of DependencyObject.GetValue in Reflector makes me think that this is non-trivial to do in Windbg. As an alternative (and a hacky one, I admit), in your own classes you could bind a standard CLR property to the Name DP, so that you do have a value that you can read in the debugger.