|
Somehow, it seems to me, that the DoWork method should do the work and that the ProgressChanged method should update the progressBar. Unfortunately this doesn't work, I get an error message at runtime.
public void bw_DoWork(object sender, DoWorkEventArgs e)
{
Random rnd = new Random();
Pen p = new Pen();
byte red, green, blue;
Line line = new Line();
for (int i = 0; i < 100; i++)
{
SolidColorBrush brush = new SolidColorBrush();
red = (byte)rnd.Next(0, 255);
green = (byte)rnd.Next(0, 255);
blue = (byte)rnd.Next(0, 255);
Color col = new Color();
col.R = red;
col.G = green;
col.B = blue;
col.A = 255;
brush.Color = col;
line.X2 = rnd.Next(0, (int)canvas1.ActualWidth);
line.Y2 = rnd.Next(0, (int)canvas1.ActualHeight);
line.X1 = rnd.Next(0, (int)canvas1.ActualWidth);
line.Y1 = rnd.Next(0, (int)canvas1.ActualHeight);
line.Stroke = brush;
line.StrokeThickness = 1.0;
canvas1.Children.Add(line);
bw.ReportProgress(i);
}
}
public void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressbar1.Value = e.ProgressPercentage;
}
When I tried this, I got an exception in the line: Line line = new Line(); because the thread doesn't have enough resources it should be a STA Thread, which means that this method uses up so much capacity that it needs to be the only Thread running.
I am new to this. I never made a program that used more than one thread, I tried but didn't succeed.
If anybody has any pointers for me, I would appreciate it.
Ranger.
modified on Monday, June 29, 2009 3:44 PM
|
|
|
|
|
Ranger49 wrote: should the code to compute the fractal be put in the DoWork method, where the progressbar is in the ProgressChanged method?
Yes.
My example was over-simplified, and putting the code to create the
lines in the ProgressChaged event handler was out of necessity. I did that
because creating lines in the BackgroundWorker thread throws an exception
because the BackroundWorker thread is an MTA model thread and creating WPF elements
needs to be on a STA model thread. Additionally, even if you create the lines in
a STA thread, you can't add them to the canvas because you can only access UI elements
on the UI thread, and a line created on a background thread can't be added to a
canvas created on the UI thread. Catch-22?
Anyway, you'd want to do as much of the calculation as you can on the background thread
(i.e. in the DoWork handler) and you have to do the UI stuff on the UI thread (the
BackgroundWorker.ProgressChanged event occurs on the UI thread).
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I will read chapters about Threading in the books I use to learn about WPF and C# 2008.
This matter is really tricky, but that this is a challenge at the same time.
I reckon it isn't possible to turn the DoWork method into the UI Thread and the ProgressChanged in the backgroundworker Thread?
But I find this really interesting.
Thanks,
Ranger.
|
|
|
|
|
The issue here is that you are trying to update the line in a none-UI thread. You have two choices; put the UI work in the progress changed event, or invoke changes to force them onto the UI thread. If it was my choice, I'd do the UI stuff in the event.
"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 have a class that is the equivalent of BackgroundWorker only STA,
but even that won't help you here.
Even if creating the Line succeeded, you can't access UI objects on a
different thread. That means accessing the canvas will fail as well.
Here's an updated example where I've kept non-UI stuff in the DoWork handler and
moved UI stuff to the ProgressChanged handler. I added a LineDescriptor helper class
to pass line info from the background thread to the UI thread:
public partial class Window1 : Window
{
BackgroundWorker bw = new BackgroundWorker();
public Window1()
{
InitializeComponent();
bw.WorkerReportsProgress = true;
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
}
private void button1_Click(object sender, RoutedEventArgs e)
{
if (!bw.IsBusy)
bw.RunWorkerAsync();
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
<code>
LineDescriptor ld = new LineDescriptor();
for (int i = 0; i < 100; i++)
{
Random rnd = new Random();
byte red, green, blue;
red = (byte)rnd.Next(0, 255);
green = (byte)rnd.Next(0, 255);
blue = (byte)rnd.Next(0, 255);
Color col = new Color();
col.R = red;
col.G = green;
col.B = blue;
col.A = 255;
ld.Color = col;
ld.X2 = rnd.Next(0, (int)canvas1.ActualWidth);
ld.Y2 = rnd.Next(0, (int)canvas1.ActualHeight);
ld.X1 = rnd.Next(0, (int)canvas1.ActualWidth);
ld.Y1 = rnd.Next(0, (int)canvas1.ActualHeight);
bw.ReportProgress(i + 1, ld); <code>
Thread.Sleep(25);
}
}
void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
<code>
LineDescriptor ld = e.UserState as LineDescriptor;
Line line = new Line();
line.X1 = ld.X1;
line.Y1 = ld.Y1;
line.X2 = ld.X2;
line.Y2 = ld.Y2;
line.Stroke = new SolidColorBrush(ld.Color);
line.StrokeThickness = 1.0;
canvas1.Children.Add(line);
progressbar1.Value = e.ProgressPercentage;
}
}
class LineDescriptor
{
public Color Color { get; set; }
public double X1 { get; set; }
public double Y1 { get; set; }
public double X2 { get; set; }
public double Y2 { get; set; }
}
*edit* Fixed bug in bw_DoWork() (see comments)
Mark Salsbery
Microsoft MVP - Visual C++
modified on Monday, June 29, 2009 4:46 PM
|
|
|
|
|
This is fun, I understand your point, will try it!
Thanks,
Ranger.
|
|
|
|
|
I have a "Queue Editor" user control that keeps a list of queues. I have an Add button that's attached to a CreateQueue Command. This binding works great. However, I have a combo box in a separate place of the application that has a current list of available queues. The first item in the list, when selected, should fire the CreateQueue command.
I can't seem to figure out how to manually fire the command. I tried using the Execute method, but it requires the target UIElement, which to me seems pointless considering that routed commands are "supposed" to touch all the controls and only be handled by those controls that care about it. The other problem is that combo box in question does not, nor should it, know about the Queue Editor else where in the application. Any advice?
|
|
|
|
|
DahrkDaiz wrote: Any advice?
Yes. Don't use a routed command - use a Mediator instead. It's far more lightweight, and you can see a sample in action in my Twitter application 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
|
|
|
|
|
You can use an attached behavior to execute the command.
Download this code from Jaime's and my training sessions.
http://www.cookingwithxaml.com/content/ChicagoLob/demos.zip[^]
Look in the Southridge project for the RibbonTabSelectedBehavior.
Then modify it for your purposes. You can also do a search on "wfp attached behaviors" and read up on these.
modified 27-Feb-21 21:01pm.
|
|
|
|
|
|
You should be able to say Source="../Images/Img.png"
This is not a namespace problem perse, just one that looks like it because of the way most people group their files into namespaces combined with how the XAML compiler/parser compiles and looks up resources.
|
|
|
|
|
Hi,
I am developing WPF custom controls. My problem is how can get an event when the user has deleted a control from the Cider (WPF designer). The Unloaded event is triggered for a control when its deleted from cider and also when the WPF Window is closed. I want a event which is fired only when a control is deleted from cider.
this.Unloaded += new RoutedEventHandler(ControlUnloadedCallBack);
.
.
.
private void FSFControlUnloaded(object sender, RoutedEventArgs e) {
}
thanks in advance,
Vinod C S
|
|
|
|
|
You can detect in code if you are in the designer, so put your code inside the event inside a block so it doesn't fire at runtime.
Christian Graus
Driven to the arms of OSX by Vista.
"! i don't exactly like or do programming and it only gives me a headache." - spotted in VB forums.
I can do things with my brain that I can't even google. I can flex the front part of my brain instantly anytime I want. It can be exhausting and it even causes me vision problems for some reason. - CaptainSeeSharp
|
|
|
|
|
Hi,
Thanks for the answer.
but what I want to know is the exact event name which gets triggered when the control is deleted from the cider. can you tell the exact event which gets triggered?
Thanks,
vinod
|
|
|
|
|
Hi
I am new in WPF so in advance I apologize if it is just a simple question
I have a vector based (actually xaml based) image in the resources
and I want to have a button that just contain that image
and I don't want to have a button that just contain that image ,I want a button that does n't have the traditional standard shape of a button, I mean I want a BitmapButton only a bitmap I want to appear instead of button , nothing else
I have a code that do this but still show that standard view that I don't like
Please Tell me what should I do to eliminate that.
Thank you
P.S
Here is the code:
<Button Grid.Row="5" Height="75" Width="220" Padding="2" >
<ContentControl Template="{StaticResource Credit-Card}" />
</Button>
|
|
|
|
|
You'll probably want to change the template of the button to give it a different
layout. The section "Creating a ControlTemplate" in the Controls Overview[^]
has an example.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi,
Is there any way to use the Application Idle event in WPF? I want to display a message when the application goes to idle period of over 5 minutes. How can I achieve this? I am using WPF (C#) 3.5 SP1. Please guide me.
Regards,
- Kunal Chowdhury ( My Blog)
|
|
|
|
|
Idle in what way ?
Christian Graus
Driven to the arms of OSX by Vista.
"! i don't exactly like or do programming and it only gives me a headache." - spotted in VB forums.
I can do things with my brain that I can't even google. I can flex the front part of my brain instantly anytime I want. It can be exhausting and it even causes me vision problems for some reason. - CaptainSeeSharp
|
|
|
|
|
idle means => user is not doing anything using any input (like: keyboard or mouse etc.). He is not using the machine for a long period (say about 5 minutes)
Regards,
- Kunal Chowdhury ( My Blog)
|
|
|
|
|
I can give you some hint..hope this help you..
Make some global variable say 'xyz' in app.xaml and initialize it to 0.
and take one timer whose code executes after each minute and increase value of variable 'xyz' by 1 and if it become 5, then write code what you want..
and for anything you do using keyboard or mouse input at that time make the value of 'xyz' to 0..
|
|
|
|
|
Dear Ravi,
Thanks for the suggestion. Actually I was not in desk at that time when u pinged me. I will check the same & will inform u tomorrow . Thanks again....
Regards,
- Kunal Chowdhury ( My Blog)
|
|
|
|
|
Ravi,
I checked the same. This will not help me in my case.
ravimori wrote: for anything you do using keyboard or mouse input at that time make the value of 'xyz' to 0..
This will be quite difficult if I use two many Windows in my application. This will also produce huge garbage code....
Lets see.... if anyone has any solution for that....
Hope, will get the answer soon....
Regards,
- Kunal Chowdhury ( My Blog)
|
|
|
|
|
Hi,
I just completed two articles on Silverlight. The first is real basic 1.0 stuff. The second is 2.0 and more architechuraly involved but geard toward developers. I would like some community feed back and any performance results you find while testing the code. I am working on an older Pentuim 4 willimina with low memory. I'm getting bad performance results, I'd like to know what beefier systems report.
Thanks in Advance,
~TheArch
|
|
|
|
|
|
I am curious to put my Out Of Browse application in Notification Area (Tray Icon). Especially when user minimizes my Out of Browser applications it should keep one ICON in Notification Area. Once he gets some alert or To-Do operation, it will show one “Notification Window” (like Outlook New Mail Notification Window). Is it possible to these kind of operations in Silverlight
|
|
|
|