Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I am building an application that has several tabs within the MainWindow view, each containing a couple DataGrids and varying bits of data. I've been researching all week on how to set the DataContext to multiple tables/objects/queries. The only answer I can seem to find from a couple different sources is to create a ViewModel container like so:
class VMContainer
{
public ViewModel1 VM1 {get; set;}
public ViewModel2 VM2 {get; set;}
}
However, I'm unable to find anything that further explains what this is doing. From my perspective, it doesn't seem like there's ever a point where the call for data is being made. Even further, I cannot fathom how to create a call that returns all of the datasets that I need into one object. Can anyone explain how this work or direct me to an article that explains having multiple sets of data as the datacontext of a view?
Edit : How do I return a dataset of datasets?
Thanks.
With a tab control, normally you would see a separate view for each tab's content, and each view would have an accompanying view-model.
A view-model provides the view with the data/properties it needs to display via data binding.
A single view-model can provide many different sets of data. When you mention a dataset, most likely this would be represented in the view-model as a ObservableCollection<T> property.
Here's a simple example of one of those properties using an MVVM framework that implements the INotifyPropertyChanged interface.
private ObservableCollection<MyDataType> myDataSet1;
public ObservableCollection<MyDataType> MyDataSet1
{
get => myDataSet1;
set => SetProperty(ref myDataSet1, value);
}
A view-model can provide many of these properties to the view.
When the view-model is instantiated you would have code that would do the data access and get the data from the database, and you would expose it through your properties so that the view can data bind to them.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
today I found a big showstopper for my programming.
There is a class
class Foo
{
classA property {get; set;}
classB property {get; set;}
classC property {get; set;}
}
And each of the classes A, B and C has svereal classes as properties too. So, my class Foo is quite nested. The claas Foo passes parameters to an option window which is opened by the ShowDialog() command.
ShowDialog()
result false -> SelectedFoo = backup / result true -> leave method
So if the user cancels the option window the SelectedFoo, which was passed to the ViewModel of the SettingsWindow gets replaced by the backup. Well, in theory. The classes are all reference type and changed duo to the data binding in MVVM. So my backup gets altered too.
How can I stop that behaviour? Is there some way to break the connection between these two classes?
There's a couple of ways I can think of.
An old pattern from wayback is to deep clone the current settings into a new object and only apply the new settings if the use clicks Apply. This way it won't affect the rest of the system until they "ok" it. If they click Cancel there is nothing to be done because we haven't overwritten anything.
Another slightly more complex alternative is to backup individual properties as required (optionally via reflection). In this mode, no deep clone is required at startup. When a user makes a change, your record the old value before setting the new. If the user decides to cancel, you playback all the changes but this time set the properties to the prior values.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Is it good approach to store all ViewModels in a CoreViewModel in order to provide communication between each other? Or better using MVVM Light framework or something similar? (I want to have no-argument constructors)
public void SetView(Type view)
{
foreach (ViewBase openView in OpenViews)
if (openView.GetType().Equals(view))
{
currentView = openView;
currentView.Reset();
return;
}
currentView = Activator.CreateInstance(view) as ViewBase;
OpenViews.Add(currentView);
}
Ed Plunkett suggests an approach I use, but I'll try to elaborate.
If I have an application that has several sub-controls (say a control per tab page in a tab control) that I want to use then the MainWindow view will bind to the main view's view model in XAML:
<Window.DataContext>
<MainWindowViewModel/>
</Window.DataContext>
The MainWindowViewModel will declare the sub-view models as public properties and in the constructor instantiate and assign a view model object to the property.
Then it is a simple question of binding the data context of a sub-control on to the relevant view model property of the MainWindowViewModel.
<Control DataContext="{Binding ExampleControlViewModel}"/>
Then if a sub-control further breaks down into smaller components, it will declare its own view model properties and the sub-views or sub-controls will bind appropriately. Thus creating a hierarchy of view models that parallel the structure in your view/control hierarchy.
Since the whole tree of view models are initiated from the MainViewModel then it is possible to use Dependency Injection to pass down objects down through the hierarchy. For example, a mediator object to allow messaging between view models or a common database access service class.
If your application opens and closes sub-windows it gets more complicated. How to do that in an MVVM way is beyond the scope of my reply. What is relevant is that you can instantiate a view programatically and inject the view model with something like this:
(new ExampleWindow() { DataContext = new ExampleWindowViewModel(_mediator) }).ShowDialog();
Where _mediator is the object I'm using for message passing between view models.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I have extensive WinForms experience, but am new to WPF. Implementing Form design vision through XAML was easy enouhg to delve into, but I'm still a little unclear on what is expected from the M-V-VM programming style. I understand the principle of separating how things look from how they behave, but doing so sensibly in some cases continues to elude me.
For example, if I have a keypad with 9 buttons, and I want a means of enabling/disabling all of them through their IsEnable property, the Form designer in me wants to address them all in a code-behind method targeting them by Design Name. What is the WPF equivalent of such an operation? Am I expected to manage a series of bools in codebehind, and bind each one in the XAML to each respective button attribute? Thanks for any guidance. If this one scenario is explained, it should be sufficient to point me in the right direction
That specific problem is easily solved with binding. You would bind your buttons IsEnabled property to a public Property in your ViewModel and based on the logic contained in your ViewModel when that property value is changed your keypad button would get enabled or disabled.
As #GCamel mentioned you could also have a POCO class that would represent your button which would implement INotifyPropertyChanged interface with one of the properties being the IsEnabled property. You would add instances of this class to an ObservableCollection and when that IsEnabled property changes your button would become enabled or disabled in the UI.
I would also strongly recommend using one of the MVVM frameworks, my personal favorite is Simple MVVM Toolkit by Tony Sneed who also has a great article about the dialogs problem mentioned by #cwap Climb Onboard on the MVVM Message Bus
ideally, you would have an observable collection of button_info with IsEnabled property, icon and text - bind the collection to whathever suitable control like itemsControl, list, or grid and associate your button_info to a datatemple...you see what i mean ? no gui, no gui, just viewmodel and binding
or like this sample ???
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have 3 ViewModels, let s say ViewModelA, ViewModelB and ViewModelC.
Each view Model has a corresponding View.
In ViewModelA I have a Public Event that I`m using send some information.
I want ViewModelB and ViewModelC to subscribe to that Event in the current/Running instance of ViewModelA?
How can I do this?
If a new a ViewModelA I will have a different instance of ViewModelA, so I need a reference to the current ViewModelA...
Note: I`m not using MVVM Light or nay other framework (yet), because I did not learn them, yet :)
Thank you.
If you are creating new views from the view of ViewModelA you can pass the reference to another view like this
var viewModelA = DataContext as ViewModelA;
var newWindow = new ViewB(viewModelA);
Then you would need to have a property in your ViewModelB
public ViewModelA MyViewModelA { get; set; }
And in your new view:
public ViewB(ViewModelA viewModelA)
{
InitializeComponents();
var viewModelB = DataContext as ViewModelB;
viewModelB.MyViewModelA = viewModelA;
}
And then you can access your ViewModelA via MyViewModelA.
I've always done it like this and haven't seen any problems so far.
1) You can implement some kind of simple Publisher/subscriber like this one on codeproject. You will be one step ahead because most of frameworks has something similar:
In MVVM light it is called Messenger:
In Prism there is EventAggregator
2) Ugly solution would be to create static event in ViewModelA, this way you won't need a reference
While you can pass references between ViewModels, it makes your app tightly coupled and not particularly scalable. Also if you decide to make a change in the future the amount of refactoring quickly grows making managing changes a lot more difficult.
Have a look at a PubSub Event framework. These are all included in MVVM Frameworks such as PRISM or MVVM-Light that you mention, but you can always add your own version if you don't want or need the full frameworks mentioned above.
Have a look here for a simple no nonsense implementation that you should be able to adapt to your own requirements.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
If we all look at the mvc diagram, the view shouldn't know the models the controller gives out to (according to msdn mvc overview https://msdn.microsoft.com/en-us/library/dd381412(v=vs.108).aspx). To me, the ViewData, ViewBag, and TempData violates this and I have been scratching my head at why these three concepts was introduced.
Maybe I am getting it wrong? I can easily pass data to the view using the models instead of these three.
Would like to know other people's opinion.
If you down vote please comment why.
thank you
I can easily pass data to the view using the models instead of these
three.
Yes definitely you can and in such case your view becomes a strongly typed view and you can see starting of your view has a line
#Model entityName
What if you don't want (for some reason) your view to be strongly typed at all. How do you think in such case you are going to pass the data to view.
That's the purpose of ViewData or ViewBaG or TempData.
the view shouldn't know the models the controller gives out to
I think you misinterpreted this line which can't be agreed upon. If your view needs data to be displayed in controls (may be an edit view), then from where it's going to get the data if it doesn't know from where to read the data.
View someway or other way must know the model data (either in form of directly passing the Model object or using any of those 3 technique).
EDIT:
Per your last comment:
can i not use this?
public class TestModel
{
public dynamic testproperty { get; set; }
}
Yes, probably you can but that's not a proper way. Try creating a strongly typed view with model as TestModel and use any scaffold template and see if scaffolding can generate a proper template.
It will not, since scaffolding internally uses reflection to go through your model properties and accordingly generate controls for those properties/members. Since you have a dynamic property, it will not be able to reflect that property. change the type to a static type like String and see it will generate a #Html.DisplayFor(modelItem => item.testproperty). That's the issue.
Even if you don't use any scaffolding template and generate controls by your hand; what type of control will you generate for your property? since it's tped as dynamic it could be anything (string, int, datetime, email...).
ViewBag or ViewData are state management technique to pass on small amount of data b/w the views or controller to views. You should always pass your data as Model object to your view as correctly stated by #SteveHarris.
Hope this makes t clear to some sense.