PRISM UserControl and ServiceReference - silverlight

I'm using MVVM in my project and here is my question. I have a View and corresponding view-model with service reference. This view contains UserControl, which have another UserControl and it also contains nested UserControl. Last UserControl have a method which creates a popup. And in this popup i need service reference from view model. Each user control has own DataContext.
Code explanation.
View xaml:
<UserControl DataContext="{Binding ViewModel}">
<FunctionsList/>
</UserControl>
FunctionsList xaml:
<UserControl>
<Function1/>
<Function2/>
<Function3/>
<Function4/>
</UserControl>
Function3 xaml:
<UserControl/>
Function3 code behind contains CreatePopup method, which creates dialog with a UserControl Function3Popup as Content. And Function3Popup should have Service reference.
What is the best practice here? I have awful solution to pass reference using binding but it seems discouraging to me.

Well, after all I've implemented popup with own ViewModel and resolved it from parent control using command binding in the nested child control. I think it's the best solution here.

Related

How can I bind Text property of TextBox (VIEW) to a vaiable (in VIEWMODEL)

I am a newbie in WPF. I was exploring MVVM Pattern for WPF applications. I am having trouble in binding Text property of a TextBox from VIEW to a variable in VIEWMODEL
Here is the TextBox from MainWindow.xaml
<TextBox x:Name="UsernameTxt" Grid.Row="4" materialDesign:HintAssist.Hint="Username"/>
I just need to know how to bind its Text Property to ViewModel Class in Class Library
Thanks
I think it's possible to give a very generic answer to this very generic question.
If the question changes context this answer is very likely to be deleted but here goes anyhow.
You want your viewmodel to be in the datacontext of the textbox. Because datacontext is inherited down the visual tree this usually means you want to set datacontext of your window to an instance of the viewmodel. Or maybe the usercontrol your textbox is in, but we know nothing about your app so let's just cover the simple scenario.
Your options are to instantiate a viewmodel using code or xaml.
If you look at this article:
https://social.technet.microsoft.com/wiki/contents/articles/31915.wpf-mvvm-step-by-step-1.aspx
That instantiates in xaml.
Note the xmlns is
xmlns:local="clr-namespace:wpf_MVVM_Step01"
That's saying where you see some bit of markup which is prefaced "local:" then go get the class out of this namespace.
To point to a different dll ( a class library ) you need to tell it which assembly. You do that by adding ;assembly=Whicheverdll to your equivalent of that xmlns. And of course that won't be local then so give it a different name. You also need a reference to that dll or project added to the entry point exe.
Once you've done all that and your viewmodel is instantiated into memory and in the datacontext of that textbox you need some sort of binding.
Which the article covers but that will be something like:
<TextBox Text="{Binding YourPublicStringProperty}"/>

Use properties of the base control that is inside the UserControl

How can I use the properties of the controls that are inside a user control without having to use DependencyProperty?
Since, if for example I want to use all the properties of a button, I would have to declare all these?
And if there is another way without user control and it is the correct one, I would appreciate it if you answered it. (Google translator, sorry)
UserControl:
<UserControl x:Class="UserControls.UserControl01"
...
>
<Grid>
<Button x:Name="uc_btn" />
<TextBox x:Name="uc_txt" />
<DataGrid x:Name="uc_dtg" />
</Grid>
</UserControl>
Code using the UserControl:
<Window x:Class="UserControls.wnd02"
...
>
<Grid>
<local:UserControl01 uc_btn.Background="Red" uc_txt.Margin="10" uc_dtg.BorderThickness="5" Margin="90" />
<local:UserControl01 uc_btn.Background="Green" uc_txt.Margin="25" uc_dtg.BorderThickness="20" Margin="5" />
</Grid>
</Window>
It is not usual to do what you are asking.
Let's consider a usercontrol which is intended to work as if it is one single control. For example a time picker. This contains two sliders which increase/decrease hour and minute. You can also overtype in the hour and minute textboxes and there's a : between the two textboxes.
This usercontrol is all about the one property though. Time. You don't care what the minutes background is externally. If this changes it's internal to the usercontrol.
In this scenario you'd usually add a TimeSpan dependency property to the usercontrol and this is the only thing anything external to it uses.
Pretty much all commercial WPF development uses the MVVM pattern and that TimeSpan would be bound to a property in the parent view's viewmodel.
That's one scenario.
Another is where a usercontrol encapsulates a bunch of UI which is then re-usable.
Styling has scope so when you apply a style to say a Button in a window then that would apply to any Buttons in a usercontrol within it. Setting their properties.
There are also certain dependency properties marked as "inherits" whose values propogate down the visual tree.
One such is DataContext and it is this which most teams would use to deal with properties within a usercontrol.
Using MVVM there would be a MainWindowViewModel.
That would have (say ) a ChildUserControlViewModel property. That would be associated with usercontrol using a datatemplate specified datatype.
You'd then bind properties of whatever is in a usercontrol to properties of ChildUserControlViewModel or properties of MainWindowViewModel using RelativeSource binding.
ViewModel first is a common navigation and composition pattern for WPF. You should be able to find numerous blogs explain it better than I can in a SO post.
Here's one:
https://social.technet.microsoft.com/wiki/contents/articles/30898.simple-navigation-technique-in-wpf-using-mvvm.aspx

mvvm Pass button click to parent

Note: this is a different question to the one here: Pass dependency property to child view
I am currently creating a usercontrol in wpf which consists of several 'screens' that the user will click through.
For each 'screen' I have created a view with it's own viewmodel (e.g. View1.xaml, View2.xaml). The main usercontrol can then access these views:
<UserControl.Resources>
<local:ModuleBaseViewModel x:Key="ViewModelDataSource" />
</UserControl.Resources>
<Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource ViewModelDataSource}}">
<local:View1 Visibility="Visible"/>
<local:View2 Visibility="Hidden"/>
</Grid>
I would like to pass a button click from a view back down to the parent usercontrol so that I can hide that view and show the next one. Can someone explain to me how to do this?
Thanks!
If you are using MVVM and WPF, chances are you are using an IoC container. Almost every IoC container contains a method of publishing an event and then subscribing to that event. In Prism, the code looks something like this:
EventAggregator.GetEvent<SomeEvent>().Publish(ParametersHere)
I would suggest you look at your options for publishing events and reacting to them. Then your parent view model can respond to the children's events.

WPF MVVM - Activate ViewModel-command by use of hot keys from MainWindow

I have an MVVM application in which the MainWindow contains a grid with several views.
In one of the viewmodels there is a command which I can activate by using hot keys in its corresponding view. I can only activate the command when I am placed in the part of the MainWindow that contains the specific view.
The following code works fine, if I only want to be able to activate the command in the specific view:
ComponentView.xaml:
...
<UserControl.InputBindings>
<KeyBinding Gesture="CTRL+U" Command="{Binding Path=UploadCmd}"/>
</UserControl.InputBindings>
</UserControl>
I would like to be able to activate the command by using the hot keys from any part of the MainWindow.
This is my failed attempt to do the keybinding in the MainWindow, so that the command can be activated from anywhere:
MainWindow.xaml:
<Window x:Class="MyProgram.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:view="clr-namespace:MyProgram.View"
xmlns:vm="clr-namespace:MyProgram.ViewModel"
...>
<Grid>
// Grid content
</Grid>
<Window.DataContext>
<vm:ComponentViewModel>
<KeyBinding Gesture="CTRL+U" Command="{Binding Path=UploadCmd}"/>
</vm:ComponentViewModel>
</Window.DataContext>
</Window>
Is it possible to somehow let the application know where the command is directly in the xaml?
Three options I can think of:
You could place your commands in your main window and then use relative source binding from the child views to the command in your main window.
{Binding Path=PathToProperty, RelativeSource={RelativeSource AncestorType={x:Type Window}}}
If you are using an mvvm framework, there is often a way to message / communicate between viewmodels. This is usually not the best solution but can be used in the right circumstance.
Use IOC / Dependecy Injection to create a service that is instantiated as a singleton in your viewmodellocator. Then inject this service implementation into the parent and child viewmodels constructors. Then you can call functions/properties from that service from the parent viewmodel that can be accessed by the child viewmodels. I use this for navigation purposes.
What are you trying to do with those commands?
Hope this helps

Binding Commands Without Using the DataContext [silverlight+prism]

Hello I have a problem with binding commands to button inside datagrid.
Here should be explanation but it doesn't explain everything.
http://msdn.microsoft.com/en-us/library/dd458928.aspx
What should be in classes in namespace Infrastructure?
Can somebody show me a really basic sample of using this?
not just parts of the code...
The Prism Commanding QuickStart - included with the Prism drop should provide the simple code example you are looking for.
All data-bindings go against the current DataContext unless specified otherwise. The DataContext is inherited down the tree of controls unless a control specifically picks a DataContext.
For example your Button might look like this and would look for the SaveCommand on whatever the DataContext has:
<Button Command="{Binding SaveCommand} />
Your button could also look like this if you wanted to bind to a command exposed on your classes code-behind:
<UserControl x:Name="UserControl">
...
<Button Command="{Binding SaveCommand, ElementName=UserControl}"
...
</UserControl>
Using DelegateCommand is just a way of implementing the ICommand you bind to and that should be visibile in the Prism QuickStart.

Resources