|
You only need to pause, if the tick event takes longer to execute than the interval if you want a "proper" timer.
And if you're re-entrant, you don't need to pause either.
Pausing implies your interval is "off".
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
In my current way to structure a WPF-application I heavily lean on UserControls for my Views and place them in the MainWindow inside a container, usually a DockPanel. For instance in the MainWindow:
<DockPanel LastChildFill="True">
<views:Header DockPanel.Dock="Top" />
<views:Footer DockPanel.Dock="Bottom" />
<views:Body />
</DockPanel> For each View I have a corresponding ViewModel. This ViewModel is instantiated inside the View's XAMl-code. In the DataContext element. For instance in the Body View:
<UserControl.DataContext>
<vm:BodyViewModel />
</UserControl.DataContext> I like this approach, because I can alter any properties in the ViewModel and see the View automatically change in the view during design time.
But I have not find a good way to access any ViewModels from some class where I happened to need to alter the View through a property in a ViewModel.
My current solution - which I don't like - to gain access of the ViewModels is:
1. Give each View a name in the MainWindow.xaml file.
<DockPanel LastChildFill="True">
<views:Header DockPanel.Dock="Top" x:Name="viewHeader" />
<views:Footer DockPanel.Dock="Bottom" x:Name="viewFooter" />
<views:Body x:Name="viewBody" />
</DockPanel> 2. Do some logic in the MainWindow to setup the ViewModels for each View.
public partial class MainWindow : Window
{
HeaderViewModel Header { get; set; }
FooterViewModel Footer { get; set; }
BodyViewModel Body { get; set; }
public MainWindow()
{
InitializeComponent();
Header = viewHeader.DataContext as HeaderViewModel;
Footer = viewFooter.DataContext as FooterViewModel;
Body = viewBody.DataContext as BodyViewModel;
}
} 3. Then for every class where I need a ViewModel I need to pass it from the MainWindow in some way.
class SomeClass
{
public void AlterHeaderText(HeaderViewModel header)
{
}
} This approach works, but I don't like it. It's annoying to pass ViewModels from the MainWindow every time a class need one or more ViewModels to alter a View.
Is there a solution to this approach to improve it?
/BR
Steffe
|
|
|
|
|
You're accessing the UC's directly: tight coupling.
Ideally, you should be communicating only with the Main Window; using methods / an interface that works indirectly with the UC's; e.g. "set heading title".
Use a static (e.g. .Current) to access "main window" and any other windows / UC's that only exist as singletons (at any given time).
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
If you have a viewmodel for each user control, why is the setup performed in the main window anything more than adding the user control to the parent content control (a grid?)? The view should do all of its own setup, and should betotally self-contained at that point. Sure, you may have some sort of global data, but in the end, the user control and its viewmodel should really be completely self-contained, and the main window shouldn't even be involved.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
Look at MVVM Light or its soom to be replacement Microsoft.Toolkit.MVVM. They have there place but personally I think they can make simple things more complicated.
So many years of programming I have forgotten more languages than I know.
|
|
|
|
|
Historically (and in my experience), Microsoft's "convenience" frameworks are too generic to be even remotely useful. And the closer you get to an enterprise-sized application, the worse it gets.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
You could use singletons. I posted an article that uses singletons for app settings, the connection string for a database, and the DAL object I use to access the database. If you look at the source code, you'll see how to do it (or at least, how I did it).
Entity Factory - Get Your ORM-less Freak On![^]
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
Alright, I'm at a loss. I'm trying to get a TextBox to display WPF's default red border around the control. I know for a fact that the error condition is being detected, but the border color isn't changing. I think I'm just bench blind, but I've been playing with this for two days now with no success. Can anyone see/think of anything I'm doing wrong?
0) I've implemented IDataErrorInfo on my control (which already inherits INotifyPropertyChanged ):
public partial class WizPgQuery : WizardPageBase, IDataErrorInfo
{
public string this[string columnName]
{
get
{
string value;
switch (columnName)
{
case "ClassName": value = this.ValidateClassName(); break;
case "QueryText": value = this.ValidateQueryText(); break;
default : value = string.Empty; break;
}
return value;
}
}
public string Error
{
get { throw new NotImplementedException(); }
}
1) I have my property and validation routines implemented
private string className;
public string ClassName
{
get { return this.className; }
set
{
if (value != this.className)
{
this.className = value;
this.NotifyPropertyChanged();
}
}
}
private string ValidateClassName()
{
string value = (this.ClassName.IsValidClassName())
? ""
: "The class name must be a valid C# identifier.";
if (!string.IsNullOrEmpty(value)) { SystemSounds.Beep.Play(); }
return value;
}
2) My XAML looks like this:
<TextBox x:Name="textboxClassName" Grid.Column="1"
Text="{Binding Path=ClassName,
Mode=TwoWay,
ValidatesOnDataErrors=True,
ValidatesOnExceptions=True,
NotifyOnValidationError=True,
UdateSourceTrigger=PropertyChanged}"
TextChanged="TextboxClassName_TextChanged"
ToolTip="Base tool tip" />
3) No dynamic/static resources defined that might override WPF's default presentation behavior
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
|
That's for setting the tooltip (on error). I just want the border to turn red (which is supposed to be the default behavior).
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
well, i created a simple app that just had a TextBox with IDataErrorInfo, and it works as expected, so now I have to figure out what I did to make this not work in my much larger and complex app... At first blush, I thought I might have done something in a textbox style somewhere, but I don't have any "global" styles for textboxes anywhere in the code.
This is gonna suck. :/
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
Hi Everyone,
Currently I am working on a Windows Desktop Application made in WPF and .NET Core 3.0. Recently my client asked me to implement push notifications in my Desktop Application. The scenario is if there are multiple users that are working on the application on different computers.. for our example lets assume 2 users working on 4 systems (each user logged in to 2 computers) and suppose User1 had done some operation on his system so I want that a push notification should go to User1 logged in on another Computer. Also, User2 should not receive any notification for obvious as operation is performed by User 1. I am not sure how to achieve this functionality in WPF based desktop application. Can some one help here?
Thanks,
Kashish
|
|
|
|
|
You're not going to be able to "push"; you need clients (software) that poll a server / database for new messages.
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
Hi Gerry,
Is there any way instead of polling the server that whenever Server push the notifications in case of any database changes i can receive it instantly. Polling will be a little bit delay. Server is in PHP and my client is WPF desktop application.
|
|
|
|
|
Along the lines of what Dave said, it is possible to "broadcast"; assuming someone is listening. Master and slaves (I've used MODBUS over serial and tcp/ip).
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
modified 14-Dec-20 1:30am.
|
|
|
|
|
Without knowing any details about your app at all (and "it's a WPF app doesn't help), you might be able to do this without a server.
The app could use UDP broadcasts to send a message out so that the same app, using UDP clients listening for the broadcasts could receive them.
The implementation details would be left up to you since you're the only one who knows anything about your app.
|
|
|
|
|
Why are ticks on a DispatcherTimer so unstable? Even at 500 msec. Is there anything you can due to stabilize it?
I am reading analog data from IO and want to update the graph of it. It does not need to be that fast but it looks odd when it keeps jumping at an random intervals. I can deal with long jumps if they are consistent.
So many years of programming I have forgotten more languages than I know.
|
|
|
|
|
I should have noted that I can do a simple while loop with a sleep in it and get better results. It still seems like the tick from DispatcherTimer should do better.
So many years of programming I have forgotten more languages than I know.
|
|
|
|
|
What interval and how far off are we talking?
Windows is not a real-time O/S, so getting an exact interval isn't possible. Events or callbacks are guaranteed to occur NO SOONER THAN your interval. That doesn't mean that it will execute ON that interval.
|
|
|
|
|
I sat the interval for 500 ms. Hard to measure but the trace has a jerky motion. It is much smoother when I use a simple while loop with a sleep in it. Setting the sleep for 20ms gives a nice smooth plot.
So many years of programming I have forgotten more languages than I know.
|
|
|
|
|
Quote: Timers are not guaranteed to execute exactly when the time interval occurs, but they are guaranteed to not execute before the time interval occurs. This is because DispatcherTimer operations are placed on the Dispatcher queue like other operations. When the DispatcherTimer operation executes is dependent on the other jobs in the queue and their priorities.
In other words, you need a separate timing device if you want "stability".
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
It is probably also effected by the debugger in Visual Studio. It really makes the DispatcherTimer useless for delays under a minute.
So many years of programming I have forgotten more languages than I know.
|
|
|
|
|
What is the difference between Show/Hide or Visible/Hidden"? I have some windows I need to keep running in the background. Searching for something yesterday I came accost a comment that said that Show/Hide are obsolete in a Wpf and I should be using the other. I cannot really find a difference except that Visible/Hidden has an event you can tie to the change.
So many years of programming I have forgotten more languages than I know.
|
|
|
|
|
|
I have a UserControl on a TabView that has a DependencyProperty of type Project. Project is an object.
public static readonly DependencyProperty ProjectProperty =
DependencyProperty.Register("Project",
typeof(ProjectEntity),
typeof(PurchaseOrderView),
new PropertyMetadata(null, new PropertyChangedCallback(OnProjectChanged)));
public ProjectEntity Project
{
get { return (ProjectEntity)GetValue(ProjectProperty); }
set { SetValue(ProjectProperty, value); }
}
private static void OnProjectChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
PurchaseOrderView control = (PurchaseOrderView)d;
control.LoadPurchaseOrders();
}
<h1>endregion</h1>
When the control is first loaded, and the binding occurs, Project is set to the instance, and everything works fine.
However, when I select another tab, the control's CTOR and DP's Changed method fire AGAIN and now Project is Null and casues null ref exceptions.
I'm not really sure what's going on. Is it unbinding somehow?? I don't really know how to diagnose this.
I found this article that discusses the Tab Control removing and replacing its content when the tabs change, and I tried using the solution, but it doesn't work.
Anyone have an ideas?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
modified 2-Oct-20 12:49pm.
|
|
|
|