|
Hello everyone,
I have canvas that contains several controls representing network nodes. There are several types of nodes. After selecting one node I need to display property page for it. Each node type has its own customize property page. For example there are nodes that can be accessed via RS232 or TCP/IP or WLAN. Property page should allow to change connection setting and display statistical info about selected connection.
I would like know whats the WPF way of doing such a thing, what would be the 'cleanest' solution?
|
|
|
|
|
A really neat way of dealing with this would be to create your property page in the Adorner layer. You can do some amazing things with this type of effect.
|
|
|
|
|
Hi again!
I need your help again, this time to paint an Oszillograph.
That's what I have so far:
void DrawSpectrum(float[] TraceData, int LeftBwPoint, int RightBwPoint)
{
System.Windows.Point[] PointsCurve = new System.Windows.Point[TraceData.Length];
float maxValue = -5000;
float minValue = 5000;
int curveCount = 0;
for (int i = 0; i < TraceData.Length; i++)
{
if (TraceData[i] > maxValue)
{
maxValue = TraceData[i];
}
if (TraceData[i] < minValue)
{
minValue = TraceData[i];
}
PointsCurve[i].X = i;
PointsCurve[i].Y = (int)TraceData[i];
}
PointCollection pointcoll = new PointCollection();
for (int i = 0; i < TraceData.Length; i = i + TraceData.Length / 20)
{
pointcoll.Add(PointsCurve[i]);
}
DrawPictureSpectrum(pointcoll);
}
Values I get are for example:
{0;-54 25;-53 50;-50 75;-50 100;-49 125;-48 150;-48 175;-48 200;-48 225;-48 250;-48 275;-48 300;-48 325;-48 350;-48 375;-48 400;-49 425;-49 450;-50 475;-52 500;-54}
That's ok, but how can I paint / present this? (minus values!)
I did this once for Windows Forms by creating a Bitmap, painting on it and passing it to a picturebox - unfortunately it seems these techniques won't work in wpf.
Help would be really apreciated, I close to throw out my notebook out of the window
no serious, please help me with this.
|
|
|
|
|
If you have the option to use the latest .NET 3.5, then check out WriteableBitmap[^] for an efficient way to plot points. This doc has an example inline.
|
|
|
|
|
Thanks for the tip, but I'm not sure if this is really "efficient". Especially the unsafe part is a bit weird for something as full managed as wpf.
What would be a better idea, or better - what would be a typical wpf approach to present data like this (and keep in mind it's being updated a few times every second).
Should I draw directly on a control (and if so how to deal with the negative values)?
If I should draw on a control, how can I do it and how can I get rid of the outdated data without producing memory leaks?
I know I'm asking for much, but I'm really stuck with this.
Nethertheless, thank you very much gurge60 for your help
|
|
|
|
|
Any direct writing to memory like that will be unsafe, but it's
also very efficient.
If you can't use unsafe code then you will sacrifice efficiency.
For example, you could use Marshal.Copy() to copy bits into and out of a
WriteableBitmap's backbuffer, but it will be less efficient.
You could also wrap a WriteableBitmap's backbuffer in a System.Drawing.Bitmap
(GDI+) and use System.Drawing.Graphics methods to draw on the bitmap, which
could even be less efficient.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi,
I am trying to create a WPF application using MVP pattern. The user of the application should be able to create customers and edit customer information. The data is stored in the SQL database at the backend.
Can any one help me by providing information regarding MVP pattern and how we can implement the same with WPF application.
Thanks in advance.
Best regards,
Sarvani
|
|
|
|
|
Rather than use the MVP pattern directly, there's a variation called MVVM. Josh Smith has recently had an article published in MSDN magazine[^] on how to do MVVM in WPF - it's a must read.
|
|
|
|
|
|
I am using a GridView inside the WPF ListView control. On display of data I perform some validations and change color of some cells in each row accordingly. The problem is that there can be thousands of such rows in the ListView (bound to an observable collection)which leads to high CPU utilization.
Is there a way that i can update only the visible rows in the listview. And as I scroll the listview down the next set of rows start getting updated.. This way the CPU utilization would be kept in check inspite of thousands of rows being updated in the observable collection..
Any help is appreciated.
Thanks.
Pankaj Chamria,
Software Programmer.
|
|
|
|
|
I would use a VirtualizingStackPanel on the listview. This is an attached property, that is used like this:
<ListBox VirtualizingStackPanel.IsVirtualizing = "True" ItemsSource="{Binding MySource}" ItemsTemplate="{Binding MyTemplate}" /<
|
|
|
|
|
Thanks for the reply. I tried your suggestion as shown below for my ListView for which the ItemsSource get assigned to an observable collection from code-behind. However it did not show any performance enhancement.. Can you check and see whether i am missing something.
Also important to note is that the datasource is getting updated continuosly using a live data stream. And i am trying to reflect those changes in the ListView.
<StackPanel Orientation="Vertical" x:Name="pnlMain">
<ListView VirtualizingStackPanel.IsVirtualizing="True" x:Name="gridControl1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
Width="Auto" Height="Auto" ScrollViewer.CanContentScroll="False"
IsSynchronizedWithCurrentItem="True" ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler"
local:ItemsControlBehavior.AlternateItemContainerStyle="{DynamicResource alternateItemStyle}">
<ListView.View>
<GridView x:Name="view" ColumnHeaderContainerStyle="{DynamicResource MyHeaderStyle}">
</GridView>
</ListView.View>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
</StackPanel>
Thanks!
Pankaj Chamria,
Software Programmer.
|
|
|
|
|
Is it your list that's being heavily hit? My suspicion here is that the ObservableCollection is actually the cause of your problem. Every time you add an item, it fires off the change notification, which results in the list being updated. To minimize the number of times it needs to update, I would consider adding the data in to the collection in reasonably large batches.
I use a custom observable collection[^] to allow me to add large amounts of data.
|
|
|
|
|
My problem is that once the data gets loaded in the observable collection for the first time, the values of properties of the objects in the collection are continuosly getting changed to the tune of 500-600 objects per second and each object has about 18 properties which get updated. The object itself is not getting overwritten/ added/ deleted. Its properties are just being modified. Also i observe that the Collection Change and Property Change events do not get called for such updates. It gets called only when the collection is first being created.
With virtualization i was hoping that although 500 objects may get updated evry sec but the UI changes will be generated only for the visible objects. But that is not the case with my usage of observable collection.
I guess due such large no of updates every second the UI sort of hangs, and CPU utilization goes 80-90%.
Any suggestions what can i try further?
Thanks!
Pankaj Chamria,
Software Programmer.
|
|
|
|
|
Wow. That sounds like a lot of notifications being fired there (I'm assuming here that you are using INotifyPropertyChanged here). You may want to put some of your processing onto a background thread.
|
|
|
|
|
The processing is actually on a background thread. And the only work that the UI thread is doing is updating itself whenever the INotifyPropertyChanged event is fired for a property. I think with WPF such high frequency of updates is bound to be detrimental to performance. I made a prototype in windows forms and that worked much better under the same load.
One more intersting point I observed is that Virtualization is by default true in ListView. Hence making IsVirtualizing = true explicitly, did not have any impact.
After trying out many options I am now gonna make use of the good old Thread.Sleep() to add re-curring delays in milliseconds while updating columns of the ListView. Its not an ideal way but i cant figure out anything else
Pankaj Chamria,
Software Programmer.
|
|
|
|
|
Hi,
I am also facing the same issue while populating the huge collection of data in an ObservableCollection & binding it to the UI.
Please help me in this case. If you have any code for this, please share that too.
Regards,
- K
|
|
|
|
|
If you're adding large amounts of data, then I would suggest that you consider my implementation of a custom observable collection here[^].
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
Yes... I have seen your link.
But, my problem is like Pankaj. I am adding a huge range of data at the first time & then on every second I am modifying the list's item properties. There are more than 10 properties. FYI, I am not adding new items, just modifying the existing data.
Due to huge property change in every second, there seems a performance issue as I am binding the data to the UI as UserControls.
How can I achieve this? Please help me out. I am using WPF 3.5 SP1.
|
|
|
|
|
Right, so you're bulk loading data and then modifying the individual items in the list, which results in multiple property changed events being raised. As only a finite amount of these items are being displayed, the first thing I'd do is wrap things up using a Virtualizing StackPanel.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
I am already using the Virtualizing StackPanel, which loads more than 200 UserControls & displays 100 among them at a time> Each UserControl consists of 10 Properties.
Is it require to use the Custom ObservableCollection?
Let me know... how I can increase the performance...
Share Code if you have one...
|
|
|
|
|
You seem to be having the same issue as i was with large number of property changed events getting raised..
Here are a few things you can try:
1) Out of all the columns make sure you raise changed events for only those properties that are changing in value.
2) In case you can afford to render the changes once every 1-2 seconds then following the approach given in the below link will be very useful. It solved my performance and UI hanging problems.
Try this Link[^]
Let me know if this helps.
Pankaj Chamria,
Software Developer.
|
|
|
|
|
|
You may want to take a look at what my friend Tamir came up with here[^].
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
Pankaj Chamria wrote: 1) Out of all the columns make sure you raise changed events for only those properties that are changing in value.
I am changing all the properties.
Pankaj Chamria wrote: 2) In case you can afford to render the changes once every 1-2 seconds then following the approach given in the below link will be very useful. It solved my performance and UI hanging problems.
Can you post your code for solving this problem?
|
|
|
|