I have a class Target and a static property, in another class, called points. Each time the user hits a target, I want to increase the points. The reason I put points in a different static class is so that each Target object can access it.
The problem is that the textblock displaying the points exists in the MainPage and not in each Target object. Since I can't bind my XAML to a static property, how can I make it so that each Target object can somehow let the MainPage know that it should update the points textblock? thanks for any advice
You could totally apply the MVVM pattern here. If there is a static ViewModel that is bound to the main window, then you can raise a notification each time a property changes and the Views (all tied windows that display the data) will be automatially updated (re-bound).
I would recommend checking Laurent Bugnion's MVVM Light framework. It has a lot of this plumbing done for you, so all that needs to be done from your side is to put the parts together and bind them correctly.
Some resources worth checking for your situation:
WPF Apps With The
Model-View-ViewModel Design
Pattern (still applied to
Silverlight as a methodoloogy)
Model-View-ViewModel In Silverlight
2 Apps
If you need samples, take a look here.
Are Class Target and AnotherClass.points within the same name space? If so, may be the following helps:
/* In Window class */
Window w = new Window();
/* function where Target get hit */
w = this;
/* code to update points */
w.textbox1.Text = AnotherClass.points.ToString();
Related
At first: This App and Question is for learning purpose
I'm on a new application and facing the problem that I want to open a Window when the user clicks on a Button in the MainView. In the past I'd have designed a Command which just creates the new Window and displays it
new RelayCommand((x)=>new SecondWindow().Show());
Now with this new Project I'm trying to fully decouple all classes from each other. To achieve this my App consists of 4 Assemblies (BL, COM, DAL and UI).
As in each WPF Application, the App starts with the MainWindow.xaml. The MainWindow.cs will create it's instance of MainWindowViewModel:
public ViewModel VM {get; private set;}
public class MainWindow(){
VM = new ViewModel();
InitializeComponent();
}
(which already violates loose coupling) (Any tips on how to make it better?)
My last attempt is to create an instance of my second Window inside my main window
<Window.Resources>
<local:SecondWindow x:Key="sw"/>
</Window.Resources>
and pass it as a CommandParameter to my Command
CommandParameter="{StaticResource sw}"/>
new RelayCommand((x)=> ((Window)x).Show());
This solution works but has one big disadvantage - the second window get's created immediately after the app starts - and so does it's ViewModel which starts some heavy processes (DB Connections etc.)
I've heard something abour IoC principle but I really don't know how to use it with an wpf application.
You are thinking along the right lines.... you basically have to create a List of ViewModels as your application starts up, then you can switch between them as the user presses buttons and pass the name of the ViewModel as a CommandParameter to your Command handler....
You might find this link to Rachel Lim's Blog
https://rachel53461.wordpress.com/2011/12/18/navigation-with-mvvm-2/
Also, I'm not going to post any code here coz it simply gets too complicated. So here is a download to just about the simplest example I could come up with
http://www.mediafire.com/download/3bubiq7s6xw7i73/Navigation1.rar
Download and un-RAR it (with win RAR) You will need to step though the code, figure out what its doing and how its doing it then modify it to suit your needs... Or modify your needs to suit the code.....
The example is a modification of Rachel Lim example. It simply contains Views and ViewModels, there are no Models or data. It demonstrates switching between two different Views.
UPDATE 1
With specific reference to the demo code.... Your VMs are added to a static collection of VMs (see AddViewModel function), each View ( the DataTemplate associates View with ViewModel) is selected when you click a button for example, by calling 'SelectViewCommand' which in turn sets Current_ViewModel to the selected ViewModel... the corrisponding ContentControl is then updated to display that currently selected View...
I know is confusing and very difficult to explain
When you press a button to 'change Views' you are actually changing the value of the property that your ContentControl is bound to, so you have to call the correct SelectViewCommand in the SAME instance of the class that your ContentControl is bound too...
In the demo you'll see that in the 'LogOn_View' I call
Command="{Binding DataContext.SelectViewCommand, ElementName=Base_V}"CommandParameter="Main_ViewModel"
Here I am calling the SelectViewCommand in the Base_ViewModel (x:Name="Base_V" in Base_View XAML), That's because I want to change the View that is displayed in the Base_View's 'ContentControl'
In Main_View I call
Command="{Binding SelectViewCommand}" CommandParameter="MainV1_ViewModel"
Here I am calling the SelectViewCommand in the Main_ViewModel, That's because I want to change the View displayed in the MainView's 'ContentControl'....
I typically create a WindowService class for managing window changes/dialogs in MVVM. Having "View" code in the ViewModel (i.e. Window.Show()) goes against MVVM principles. For example:
public class WindowService : IWindowService
{
public void ShowDialog<T>(ViewModelBase viewModel) where T : IApplicationDialog
{
IApplicationDialog dialog = (IApplicationDialog)Activator.CreateInstance(typeof(T));
dialog.Show();
}
}
And then your call from the ViewModel would look something like:
windowService.ShowDialog<SecondWindow>(new SecondWindowViewModel());
If you're using DI, you can pass a reference to the IoC container to the window service and create the window instances from that rather than using Activator.CreateInstance (i prefer the DI approach personally)
I'm working on a Unity project. It's a visualisation software, so most of the game mechanics are based on buttons, sliders, color-picker updating my GamesObjects.
I can't figure out how to organise my UI implementation.
Is it a good idea to apply some kind of MVC pattern to unity, any idea how to do it (I found some article about that but they weren't clear to me) ?
Currently I'm adding UI elements in the scene. An empty game objets called UIManager is holding scripts concerning the UI. Those scripts hold references to UI elements, add a listener to them and contain methods called by the event.
My approach is correct? How to improve it?
My UI Manager contain scripts like this one :
public class someMenuGUI : MonoBehaviour {
public Button enable;
public void Start()
{
enable.onClick.AddListener(Enable);
}
public voidEnable()
{
GameObject[] Objs = Object.FindObjectsOfType (typeof(GameObject)) as GameObject[];
// then do something on them
};
That's a very good question without an answer that can be considered to be universally true. However, I would like to share my approach to this.
When I write Unity code, I have two categories of users in mind: players and designers. Essentially, since almost all Unity code is contained in MonoBehaviours, and MonoBehaviours are used in the editor, you're constantly writing a tool for designers that they use to actually create a game.
Even if you don't have a designer and work alone, it's useful to think about code in this terms. This way, you have a clear separation between code space and editor space: code doesn't have to make any assumptions about what happens in the editor; instead, designer has to be able to use your components to build what they want.
So, where do you draw the line? I think that if you're going to use the MVC pattern, the separation is quite clear: the controller logic should be contained in code, but the wiring up of the actual UI elements should be in the hands of the designer. Which, finally, brings us to the code.
A great way to implement the MVC pattern is to use events instead of solid references: this way the controller and the view don't have to know each other's types, they only have to know the model. But since you want the designer to hook events up in the editor, you can't use C# delegate events. Thankfully, there's a new feature of Unity's UI system just for that: UnityEvent.
So, let's say that your script, which plays the role of the controller, has to have two-way communication with the view: from controller to the view to update the information, and from view to controller to run the user's action. Turns out, it's very simple to set up. Create a public UnityEvent (with a correct generic argument) for update of the data, public method for user action, and you're done with the code! All that designer will have to do is to set the Unity event on your script to update the UI, and to set up Unity event of UI element to call your controller's method.
First of all, let me apologize for the super-noob question about WPF and binding. I have started, a few days ago, to get interested in WPF and its implementation with XAML markup and C# code-behind in Visual Studio Express 2013, and I'm trying to bind the contents of a button to a property that is part of a singleton class. And I can't, apparently.
What I want to do is this:
I have a button saying "Start" and I want, on click, to have the button contents change to a timer + stop, something like "00:00:02 -- Stop" and, on click again, to have it change back to "Start".
I have this class that I have designed as a singleton to prevent it from being instantiated more than once, which contains an instance stopwatch of System.Diagnostics.Stopwatch, and a string property which I change either to "Start" or stopwatch.Elapsed.TotalSeconds.ToString () + "Stop" back and forth.
The problem is that when I try to refer to my singleton class in the XAML markup, like so (to be honest, I don't really know what I'm doing, I'm just inspiring myself from diverse examples I've found over the web):
<Window
...
xmlns:local="clr-namespace:myNameSpace">
<Grid>
<local:mySingleton x:Key="myStringProperty" />
...
</Grid>
</Window>
I get a slew of compiler errors (6 total) of which some say: "The type mySingleton does not include any accessible constructors." and "The "Key" attribute can only be used on an element that is contained in "IDictionary"."
I'm clueless as to what to do, knowing that I don't want to make the constructor public (and therefore get rid of the singleton thing).
Any pointers towards the right direction ?
Thank you guys for your help.
At first you have problem in displaying your string property. You have to use text box and then use property for text binding:
<TextBox Text="{Binding Path=myStringProperty}"/>
Also you have to set your class (view model) to the Window.DataContext and your property have to call OnPropertyChanged event (see: WPF: simple TextBox data binding).
Now about singleton. The singleton shouldn't be used for this. You should have window (view) and that window have to work with some class (view model, you have one instance per one window) and if you want to run more windows together and you always want same result, then inside that view model you should have some static object (it can be that timer, or some class which will handle requests about get result from timer which will inside that class what can be singleton). So it could looks like Window (view) -> view model class -> static timer / class which will works with timer inside itself.
In my MainPage.xaml, I created a Pivot Control: <controls:Pivot Title="Powder God" Name="PivotControl">.
My first pivot view is a HubTile that summarize all other individual pages. So my application bar will be different between the first pivot view and all other ones.
That's why I put my application bar in App.xaml's resource section, then load based on selected index of my pivot.
My question is:
In the application bar I will be using for all individual pages, I want to have a delete option, where I will remove that specific item (a view model) from my data context.
I know I can use PhoneApplicationFrame root = Application.Current.RootVisual as PhoneApplicationFrame; to access navigation services, but I don't know how can I reference to my pivot, so that I can get the selected index and proceed forward.
Thanks!
Using MVVM you SHOULDN'T do this:
((PageType)Application.Current.RootVisual).PivotControl. //Blah
PageType is whatever type PhoneApplicationFrame is that contains your PivotControl. If this doesn't work you need a Property in the RootVisual
PAGE
public Pivot MyPivot
{
get
{
return PivotControl;
}
}
APP
((PageType)RootVisual).MyPivot. //Blah
On one level Microsoft's suggestion of putting the ApplicationBar in App.xaml is great as it can be referenced from everywhere and would appear to encourage code reuse: however this question highlights the limit to this approach. An application bar is typically used to provide actions which are specific to the current page (or pivot item) and just because the buttons are the same you may not want the exact same code to run in each case.
In this case I think it would better to create a factory method that creates your common ApplicationBar with the click handlers you specify specific to your page/pivot item. For bonus points put the method in a new class (not App) so it doesn't get lost in all the boilerplate code there. Call this factory method in your page constructor and remember your ApplicationBar in your class. For multiple app bars, create them all up front and you can then easily switch between these app bars in your Pivot SelectionChanged code.
The alternative of creating the ApplicationBar in App.xaml and then retrieving this from the App.xaml.cs "Resources" ResourceDictionary in code, modifying the click callbacks, is more complicated in my opinion.
I wish they'd done a better job of implementing the ApplicationBar so people wouldn't want to do this. I've found that using the ApplicationBar forces you to add code to your Page.xaml.cs even if you use a framework like MVVM Light. This is still OK in MVVM as it's UI specific code that belongs in the View, but it makes things inconsistent if you're using ICommand everywhere else. Last time I decided it was better to create the entire ApplicationBar in code rather than hack this kind of thing via App.xaml.cs.
Update: There is a UserVoice request for a data bindable ApplicationBar.
I'm in the beginning stages of designing an application using Prism and have a question. In all the reference material I've been able to find, there is lots of details on creating a single screen application, but I have a requirements beyond that.
I would like the have two windows showing (Multi screen), both with the exact same layout but each looking at a difference source of information for their data. In other words, I have datasource A and datasource B that update very frequently and I need to monitor both of them at the same time.
Is there a way to launch a prism app multiscreen in this manner or would it better to launch separate processes for each source?
Thanks.
This should be pretty simple. Launching a new Window for each ought to do what you need (the user would have to move the window to the second monitor... I suppose you could investigate some p/invoke magic to move the window to the proper monitor if you wanted).
Do you need something more complicated?
If it's the same view with different data, I'd use MVVM and spin them off sort of like this:
MyFirstViewModel vm1 = new MyFirstViewModel();
MySecondViewModel vm2 = new MySecondViewModel();
MyView view1 = new MyView();
view1.DataContext = vm1;
MyView view2 = new MyView(vm2);
view2.DataContext = vm2;
view1.Show();
view2.Show();
Hopefully your view models can be reusable too so you wouldn't need to write a class for each, but hopefully this illustrates the strategy a little.