I've recently built a Volley Scoreboard Application in Windows Forms that I'm trying to convert to WPF.
My first Window has all the controls to manage the game, while the second one is the window that will be projected on the big screen.
In Windows Forms I was able to update both labels (example, home_score on both Main and Projected) from a single point in code, but I don't seem to find a way to do this in WPF.
Any chance I'm missing something? Relatively new to WPF.
If it makes sense to have both pages (Views) utilizing the same View Model; which it sounds like it might given your use case, then the answer is simple:
Bind both labels (really, TextBlocks) to the same property. When the
property is updated; the binding engine will update both UIs.
If that isn't an option; the "master" View Model could invoke a method on the Model that would raise an event (ScoreUpdated). The "display" View Model would register for this event and update an appropriate property so that its View will pick up the change.
You need to:
to name the label (TextBlock Probably) in the xaml (Name="ScoreLabel")
keep a reference to the instance of the window.
after this:
otherWin.ScoreLabel.Text = "123";
Related
I'm new to WPF and MVVM and attempting to write a firmware programmer so I can update stuff via USB and save and upload setting/state data. MVVM seems like it could work for this. I currently have pages and can navigate around the app (although the nav service is in code behind for now) but I'm stuck on how to implement things that aren't in the standard 'customer'/'person' examples.
On a couple of pages, there are subsections that I can see being sub-divided into separate views hosted in the page, and these subsections are used more than once in the app.
For instance, I want to have a TextBlock that displays the connection status and updates based on signposts in the connection process, firmware update, backup, etc. Progress bars with the % are another. Sections that are used to display errors, data or a selection box depending on what happens connecting would be another.
Having a sub-section house 3 completely different outputs all stacked on top of one another and shown based on the situation seems messy. I can see that section being a ViewBox and creating a unique view for each case being a better solution there (and possibly the other examples above).
Or take the 'status display', I can see implementing it as it's own view and the page's view model will use a messenger to pass the current status back to the 'status display' view model. I can also see it all just handled by the page's view model via calls to it's own methods. I can also see potentially using a global model to hold the status strings (maybe an enum?) and the view model can be made to pull the correct string into a 'currentStatus' variable.
What is the proper way to approach this? Keep it all a single page? Subdivide the dynamic/changing parts from the static parts?
OP:
Obviously the pages themselves are views, but would it be best to have the 'Status:'display TextBlock and it's value, and the Error/selector section be views also?
If you are asking whether the status and error displays should be UserControls then yes they can be "a view" irrespective of whether the control is using a view model or not.
Incidentally, it is generally better to use DependencyPropertys instead of view models in a UserControl otherwise you will end up having duplicate properties in both the view (so that MainWindow can databind to it) and in your control's view model (purely for the benefit of the user control).
If your UserControl uses DependencyPropertys then both users of the control and your view can both databind to the same set of properties without duplication. In this way you will realise that UserControls have no need for a separate VM.
OP:
...the page's view model will use a messenger to pass the current status back to the 'status display' view model...
Don't do this, this is what data binding is for.
First of all i'm a newbie on MVVM pattern and C# / XAML developpment. Sorry for the inconveniant.
So the aim is to create a complete application including buttons, tabcontrol and use bindings and commands to gather them all correctly.
Each button represent a specific object which has its own information (name, id, serial number, ...). All these buttons are represented in a specific view which is on a top of the window. At the bottom of this window, i need to show a table with several items and content inside associated to the button pressed.
The problem here is the table. I need to display the information of the clicked object inside the table and the content inside can vary for all tabitems. And one other thing is that when one button in particulary is pressed, the view of the table totally change and display other information.
My questions are :
Do i need to create one model for each of my button / object AND an associated viewModel to it ?
The view including all of the buttons can be a separated view from the table and both of them will be in MainView ?
Can i represent data inside the table like a scrollviewer and is it possible to add new line wih other informations from the model when click on it ?
I hope my explanation is enough to helpor so here is a schematic representation of my application showing different context.
enter image description here
enter image description here
Thanks all of you for your help.
Do i need to create one model for each of my button / object AND an associated viewModel to it ?
You can go both ways. If your model communicates with different API and requires you to use different contract then yes use different models. Otherwise I would suggest using one. About ViewModel it is as well up to you it could be done both ways. I would suggest separation but as of in question I did not find any information about the size of the application itself so it all depends on the size and concern segragation.
The view including all of the buttons can be a separated view from the table and both of them will be in MainView?
You still need root view so everything should in the same view. I could suggest creating a new UserControl for each of the TabWindows then simply just collapse or make it visible depending on button command invoked.
Can i represent data inside the table like a scrollviewer and is it
possible to add new line wih other informations from the model when
click on it ?
You can add ScrollViewer into each of the tabs in TabControl. I am not quite sure what is the question on the second part of it but I would suggest to use ObservableCollection with ItemsSource to dynamically add items to your data table.
More information about MVVM pattern and its applications can be found here.
I am not using anything other than a simple WPF application project in visual studio. I've implemented an mvvm application.
I want to display a list of content changes made by a user. I have a main window view model and it currently just builds a strings with changes. I have objects that I can reuse to display their properties (the content).
Currently, I use a MessageBoxResult to show a really long string with the changes. This is a terrible design (I know), but I couldn't really find an answer to what class a regular wpf project has that would allow me to achieve what I want.
I know there is a popup class I can use. In practice, which is better-- another view model for the dialog, or a popup?
Can anyone provide a simple example of one of the two approaches?
Thank you in advance for your response.
What I've done in the past is have a simple Border control, and inside of a TextBlock and whatever Button controls I need. I bind the TextBlock.Text to a public string property named "MessageBoxMessage" which calls OnPropertyChanged(). I bind the Command of each Button to a separate public ICommand which specifies what action to take in the view model when the button is clicked. I then bind the visibility of the Border control - which contains all of the other controls I mentioned - to a Visibility property.
When I want to show a dialog, I set the MessageBoxMessage to the message I want to show, makes sure the commands are set properly, and then set the Visibility on the Border to Visibility.Visible. This shows the box (border), message, and buttons.
You can even implement a semi-transparent rectangle underneath the border (over the rest of the form) that you set to visible at the same time. This will give you the nice "form dimmed" effect and also block the normal form controls from being clicked. A general note - for this to work, these controls need to be at the very bottom of your XAML as the z-index among controls at the same level is inferred from their placement in the XAML - lower in the code is top level on the form.
Let me know if you have any questions about implementing this if it sounds like what you are looking for.
I am writing a little piece of MVVM for training to wrap my head around the feature.
I have created a Model for my Image model class so that each Image item contains an ID, Name, Link and other stuff like height and width etc.
I have created a View as well to show the data. Nothing fancy. Just a simple ItemsControl that gets put inside my MainWindow Grid on startup.
I am now creating the ImageViewModel class which is where I am stumbling a little.
I have defined that class as such - not sure if I did that correctly:
public class ImageViewModel : Screen
I have also written some code that the software should perform to go get the data from the net and just parse stuff and retrieve a new Image item for each available new item on the net. the code should work fine as it worked perfectly when i coded this without the MVVM feature.
My issue is that i do not know how to make the action (called public void FindNewImages) launch the second the View is loaded inside my MainWindow grid on startup... How can I achieve this?
It depends on how you've wired up your view and view models. It sounds like you may be doing view first, where your view model is a resource of the view. In which case, you can invoke your FindNewImages method in the constructor of the view model.
I would however strongly recommend that you use an MVVM framework, such as Caliburn.Micro which provides screen life cycle. In this case, you could use a view model first approach, and invoke your method in the OnActivate method of the Screen type provided by Caliburn.Micro.
i originally had a main form with 2 panels, one had a graph in that i clicked on the other had the results displayed related to what you clicked.
All this code was dumped in the main form.
I tried to be a smart alec and use inheritance, so now i have a main form which has a graph objet and i have a superclass graph -> subclass specific graph heirarchy
however now when the graph is displayed in the main form, how do i get the data back to display in the other panel? The reason i ask this is now that the graph stuff is in its own heirarchy, it has no knowledge of the panel on the main form so i have no hwere to set the data when it is set
i hope someone can help
thanks
edit: i think i might just pass the control collection for the panel in to my graph class so i can add the relevant items in there
Depending on the relation between the two forms, you can use events to message data between them.
A click event handeled in the graph can raise an event with the data you need to display, which would end up on the owning form. Depending on the relationship, you either call a function on the 2nd form to display the data, or raise an event to which the 2nd form subscribed to send over the data.
[Edit]
I read Forms instead of Panels.
The main idea remains the same though. From your style of writing, it looks like you have an Objective C history. I know on the Mac, these things would be done in Interface Builder, setting bindings to make this stuff happen, but in the .NET Winforms you do these things in code (handeling events, calling methods, etc). If you like to stick more to the way it's done with Interface Builder, you might want to take a look at WPF applications; bindings work in a very similar way to how it's done on the Mac.
I would design this as an object that aggregates another object. Have a look at the way master-detail view works.