|
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?
|
|
|
|
|
Help,
I'm at my wits end. I have been working for days trying to execute the simplest task. Here is the basics of my WPF project.
I have a main form.
I have a Dialog.
I have a class module that handles serial comm
When I receive data on the serial line, I want to launch the dialog. My main form has an instance of my dialog. My main form also contains an instance of my serial comm class. When instantiating my comm class I pass a delegate sub to be called when data arrives on the serial port. So far so good.
The sub gets called when data arrives on the port, but when I try to launch my dialog I get the message "The calling thread cannot access this object because a different thread owns it".
What am I missing here? I have tried instantiating the dialog within the serial comm module but get the error that the instantiation must happen from an STA thread.
I have been googling for days, but each delegate example is different than the next. I'm not even sure that the delegate handling is my problem.
I apologize if this seems like a simple question, I am new to WPF and do not yet know what I don't know. None of the books I've purchased seem to go into any detail regarding my particular situation.
Thank You
|
|
|
|
|
frosty_4th wrote: "The calling thread cannot access this object because a different thread owns it"
You are trying to access the UI from a non-UI thread.
In WPF, you need to use the Dispatcher for cross-thread UI interactions.MSDN[^]
e.g.,
public void Test()
{
Button theButton = button1 as Button;
if (theButton != null)
{
if (theButton.Dispatcher.CheckAccess())
{
theButton.Content = "Hello";
}
else
{
theButton.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
(Action)(() => { theButton.Content = "Hello"; }));
}
}
}
|
|
|
|
|
Sacha Barber proposed a fantastic extension method that you might want to look into. It's called InvokeIfRequired, and looks a bit like this:
public static void InvokeIfRequired(this DispatcherControl control, Action operation)
{
if (control.Dispatcher.CheckAccess())
{
operation();
}
else
{
control.Dispatcher.BeginInvoke(DispatcherPriority.Normal, operation);
}
} Then, it's simple to do:
Dispatcher.CurrentDispatcher.InvokeIfRequired(()=>{ theButton.Content="Hello"; });
|
|
|
|
|
|
|
when u get the solution pls post it
|
|
|
|
|
It's already been posted in this thread. Which bit confused you?
"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've got a util class which contains a non-Generic Hashtable.
class Person
{
protected Hashtable _lstProperties;
public Hashtable Properties
{
get { return _lstProperties; }
set { _lstProperties = value; }
}
}
And property really is a template class ...
class Property<T>
{
...
}
And Silverlight stipulates that every collection be System.Collections.Generic - this means even if I hand out the source code, it can't be consumed from Silverlight.
Is Silverlight Team basically saying there'll be no need for collection of unknown types in future? That everything SHOULD be know in compile time? They actually call Hashtable OBSOLETE? Anyone has email to silverlight and WPF team?
|
|
|
|
|
Dictionary<TKey, TValue> would be the class you want I believe.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
wrong answer - you're assuming
a. you know person's property type in compile time
b. all properties of same type
dev
|
|
|
|
|
devvvy wrote: wrong answer - you're assuming
Wrong complaint department. I'm just passing MS's recommended replacement.
(or don't shoot me, I'm just the messenger )
AFAIK only generic collection classes will be used in Silverlight, as you've read.
The choice was made for framework size and performance reasons, as were many many other
trade-offs.
If you want to plead your case, you could post on the Silverlight Forums[^].
I'd be interested in MS's response...
Cheers,
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: If you want to plead your case, you could post on the Silverlight Forums
You already did - never mind
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Some other guy gave me a suggestion
Dictionary<string,>
This will do!! I may not know what sort of object it will be in runtime but I know they all derived from "Object"
I am an idiot, forget my comment!
dev
|
|
|
|
|
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Isn't Dictionary<object,> giving you all you need?
|
|
|
|
|
Yes! Thanks I am an idiot!
dev
|
|
|
|
|
|
I have problem with selected rows in DataGrid from WPF Toolkit. I have Observable Collection as ItemsSource.
I created small sample application. I´m adding file adresses to DataGrid and when I click on row in DataGrid I´m testing existence of file. If file doesn´t exit I remove that selected row automatically from DataGrid (ObservableCollection).
Problem is, that sometimes after deleting a row from DataGrid, previously selected row still remains as selected (blue background of row). But that row isn´t selected, because when I click on buton „Delete selected row“ I recieve message that no row is selected.
Exactly: When I have in DataGrid selected row (x) and a click on row (x + 1) and file doesn´t exit at row (x + 1), that row (x + 1) is automatically deleted and no row is selected - everything´s all right.
But when I have selected row (x) and a click on row (x - 1) and file doesn´t exit at row (x - 1), that row (x - 1) is deleted but row (x) still remains as selected (blue background of row x) - PROBLEM.
Doessomebody know please how to solve it? I need to have all rows visually unselected every time in my application after deleting a row in DataGrid (white background of all rows).
Here´s my code:
Window1.xaml
<Window x:Class="DataGrid.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dg="http://schemas.microsoft.com/wpf/2008/toolkit"
Title="Window1" Height="300" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="9*" />
</Grid.RowDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<Grid.ColumnDefinitions>
</Grid.ColumnDefinitions>
<dg:DataGrid x:Name="dataGrid"
Grid.Row="3"
Grid.ColumnSpan="2"
SelectionChanged="dataGrid_SelectionChanged"
Grid.Column="0"
CanUserDeleteRows="True"
Loaded="dataGrid_Loaded"
IsReadOnly="True"
SelectionUnit="FullRow"
SelectionMode="Single"
CanUserAddRows="False"
Visibility="Visible"
Margin="1"
Background="White"
AlternationCount="2" />
<TextBox Name="textBox1" Grid.Row="0" Grid.ColumnSpan="2" />
<Button Grid.Row="1" Name="Add" Click="Add_Click">Add address to DataGrid</Button>
<Button Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" Name="Delete" VerticalAlignment="Top" Click="Delete_Click">Delete selected row</Button>
</Grid>
</Window>
Window1.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Collections.ObjectModel;
namespace DataGrid
{
public partial class Window1 : Window
{
ObservableCollection<files> obs_col;
public Window1()
{
InitializeComponent();
obs_col = new ObservableCollection<files>();
}
private void dataGrid_Loaded(object sender, RoutedEventArgs e)
{
dataGrid.ItemsSource = obs_col;
}
private void dataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Files selectedFile = (Files)dataGrid.SelectedItem;
if (selectedFile != null)
{
if (!File.Exists(selectedFile.File))
{
obs_col.RemoveAt(obs_col.IndexOf(selectedFile));
}
}
}
private void Add_Click(object sender, RoutedEventArgs e)
{
obs_col.Add(new Files(textBox1.Text));
}
private void Delete_Click(object sender, RoutedEventArgs e)
{
Files selectedFile = (Files)dataGrid.SelectedItem;
if (selectedFile != null)
{
obs_col.RemoveAt(obs_col.IndexOf(selectedFile));
}
else
MessageBox.Show("No row is selected");
}
}
}</files></files>
Files.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DataGrid
{
class Files
{
public string File
{
get; set;
}
public Files(string file)
{
this.File = file;
}
}
}
|
|
|
|
|