I have a data packet, that body is consist of byte array. Also I need interprete a packet fields in few variations, but the body is still constant. For example:
AA-BB-CC-DD-EE-FF - constant packet's body.
In first interpretation: AA-BB-CC - as a Parameter 1 and DD-EE-FF - as a Parameter 2.
In second variation: AA-BB - as a Parameter 3, CC-DD - Parameter 4, and EE-FF - Parameter 5.
And so on.
I see few options to realize such behavior:
In single class create all of the needed properties (parameter 1...parameter 5), and in caller class check the variation flag.
Create few derived classes, and each class contains only specific properties (parameters 1 and 2 in first case, parameters from 3 to 5 - in the second).
Now to show packets in WPF I use 1st option. I have ListView and it's style as GridView:
<ListView x:Name="lv" />
When I need to visualize packets in first interpretation:
lv.Style = CType(TryFindResource("packetsStyle_1"), Style)
The packetsStyle_1 contains columns "Parameter 1" and "Parameter 2".
When I need to visualize packets in other interpretation, I just change the style of ListView:
lv.Style = CType(TryFindResource("packetsStyle_2"), Style)
The packetsStyle_2 contains columns "Parameter 3", "Parameter 4" and "Parameter 5".
This kind of realization is not object-oriented, as I understand. I want to do this with the OOP (option 2) - base class of packet with common properties and inherited classes with specific properties. But what is the WPF way to refresh GUI in this case?
Do I need create two objects List(of PacketVar1) and List(of PacketVar2) and change ListView item's source and style? But list of packets is huge enough, and takes a lot of memory. Or what is the right implementation?
Related
I have a form in vb.net with LOTS of text- and comboboxes. Now i do want to apply some settings to them, e.g. visibility, location and so on during runtime. The information on what to apply is complex and is stored in my database together with the name of the given item, e.g. name=textbox1, visibility=true, location x = bla, location y= bla and so on.
My question is: Is it somehow possible to use the string in the field "name" to adress the object in the code like this:
ConvertToFormObject(name).visible=visibility
so that i could apply the settings with a single loop rather than hardcoding the information in the database to all the items. Also the settings should be applied spontanously, when e.g. some event triggers were triggered.
Thanks!
You can index the Controls collection of the form by name to get the control with that Name value, e.g.
Dim cntrl As Control = Controls("TextBox1")
This assumes that all the controls of interest are on the form directly. If they are all in the same child container then use the Controls collection of that container. If they might be in different containers, e.g. a Panel and a GroupBox, then you can call Find, e.g.
Dim cntrl As Control = Controls.Find("TextBox1", True).First()
Note that Find returns a Control array, because the Name of each control in a container must be unique but multiple containers can each contain a control with the same Name. Assuming that you have used unique Name values form-wide, you just call First or Single or index the array with zero.
In wpf with mvvm I use a ListBox with Canvas as ItemsPanelTemplate and DataTemplates to customize appearance.
I would like to improve performance by first adding all items of type 1 to the drawing, then all items of type 2.
I could create two ListBoxes both with Canvas as ItemsPanelTemplate and they would be overlays.
Panning and scrolling could be synchronized by means of bindings.
This way I can raise PropertyChanges for both lists independantly from each other.
Question: do you have experience whether overlaying canvases is good or bad for performance?
I an not sure whether this is also possible using a CompositeCollection for the ItemsSource of one ListBox. Or for that matter give both types a common subclass and stay with ObservableCollection.
Question: do you think that somehow a list with CompositeCollection can be given separate PropertyChanges for different parts of the Collection?
EDIT:
Suppose I have a great number of points, lines, labels for the canvas, each of a different type, however with a common base type. I select the DataTemplate using DataType: DataType="{x:Type my:Point}", DataType="{x:Type my:Line}" etc.
First as quicly as possible I want the user to see the lines. I raise PropertyChanged("Lines") and the ListBox+Canvas for the lines is visible.
In a backgroundworker I raise PropertyChanged("Points") and the ListBox2+Canvas2 for the points is visible.
When done in another backgroundworker I raise PropertyChanged("Labels") and the ListBox3+Canvas3 for the labels is visible.
There's a much simpler solution using basic Object Oriented Programming. Create a base data type and make all of your data objects extend from it. It could be empty, but if nothing else, you could implement INotifyPropertyChanged in it so you don't have to in each of the other data types.
Then you simply add a property of type ObservableCollection<BaseClass> to your view model or code behind and data bind that to the ListBox.ItemsSource property. As long as you don't set the x:Key values on the different DataTemplates, then WPF will implicitly set them to the relevant data type objects when it renders them.
So you can put all of your different data types in the same collection. Then you can add your first type in and wait for however long and add some of a different type, or whatever order you feel like.
UPDATE >>>
In response to the edit in your question, I don't quite understand the reason for you trying to use the INotifyPropertyChanged interface to show the items, type by type. If you have the base class collection that I mentioned above, then you simply add the instances of the first type to the collection first, so they'll appear first. When you want the next type to appear, just add them into the collection and then they'll appear and so on. The ObservableCollection will take care of that.
I have 2 different ProgressBars with 2 different custom styles. In each of them, Color of the ProgressBar is Calculated based on Maximum and Value (with 2 different formulas).
I see that the type of the ConverterParameter in a converter is String.
Now I'm wondering should I write 2 different MultiValueConverters for each of them, or write a single MultiValueConverter with a Parameter and let the Parameter decide which formula should be executed.
These 2 ProgressBars are probably the bottle-neck of my MVVM's View, so I need to know which one is better in performance?
Write one converter - it makes no sense to have multiple converters for the same purpose.
Indicate which formula you want to use by using an enumeration - the value can be explicitly mentioned in the XAML.
If you want to bind external values in to your converter it will need to derive from DependencyObject and the properties will have to be dependency properties.
I'm using an ItemsControl that is populated with a collection containing several different data types. Each data type has its own DataTemplate, and they are all displaying correctly, but my problem is this: when there are several of the same type displayed one after another, the first one must display a header above it, and the last one must display a horizontal line below it. Is there a way to detect this in XAML, or do I need to pre-process this list a little to set flags?
The data is as follows:
Patient
Test
Result <-- header before this
Result
Result <-- line after this
Test
Result <-- header before, line after
Patient
Comment <-- header before this
Comment
Comment <-- line after this
Test
Result <-- header before, line after
I don't want to group the data types before displaying, they need to be displayed in the order in which they arrived.
You need to ask next/prevous sibling of each item about its type, and compare it with current item's type, and take into account that if both are equal and equal to the item, you do nothing... definitely you cannot do this with pure xaml.
Te easiest way to me would be to implement two bool properties in the viewmodel of the items 'HeaderVisible' and 'BottonLineVisible' and handle the logic there. Bind triggers to them in the DataTemplate to add top/bottom line as needed.
I think you would benefit from binding your ItemsControl to a resource key of a CollectionViewSource defined somewhere. You might be able to use the CollectionViewSource.GroupDescriptions[1] to show this in the UI.
Look at ItemsControl.GroupStyle[2] for how to style this.
[1] http://msdn.microsoft.com/en-us/library/system.windows.data.collectionviewsource.groupdescriptions.aspx
[2] http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.groupstyle.aspx
I'm trying to read a table from an Excel file (.xls) and display it in a DataGrid. The table has unknown dimensions and each column has values of one unknown type (string, double or int).
I access the file via COM and put the table in a List<> of ExpandoObjects. When I set DataGrid.ItemSource to the List the Grid remains visually empty.
Explicitly defining columns and their data binding yields the runtime message that the application can't find the specified properties in the ExpandoObjects.
How can I display the table in the GridView? I work with Silverlight 5 RC and was hoping for a simple way to do it. At least simpler than the solutions I saw for Silverlight 2 and 3 so far.
If it's dynamic and it doesn't implement ICustomTypeProvider, in Silverlight 5 it will not bind. It's really unfortunate since we have dynamic databinding in WPF, and in the case that properties can be known (like Expando), even writing a CustomType that would work for any IDynamicMetaObject provider isn't difficult, not to mention they could have just added it for Expando, especially since it's sealed.
So the bottom line is that you need to write your own dynamic type implementing ICustomTypeProvider
I realized Vladimir Bodurov's solution works fine for me. I replaced the ExpandoObjects by Dictionaries and used Bodurov's class to transform the List into something the DataGrid can process.