|
Hello,
On my WPF App in the main window i have a treeview control on the left and a border control on the right,
I want to display different user controls in the border according to selected item in the treeview using MVVM pattern.
Didn't find any good example, can any one guide me?
Thanks
|
|
|
|
|
Put a content control inside of the border and bind it to a content property on your ViewModel. Use the Interactivity library to attach a command to the selected node change event or the EventToCommand helper in MVVM Light. In either case, the command handler in your ViewModel will set the content property on the VM to an instance of the user control you want to display. The binding will automatically pick it up and display it inside the content control.
Your user controls can each have their own view model to handle their functionality. In this way you essentially swap encapsulated views/viewmodels in and out of a container at will.
|
|
|
|
|
Thanks for the answer,
One question though, if i will set the an instance of my control inside the VM ,that means that my VM has to know about the different controls,doesn't it against the MVVM pattern concept(the view is isolated from the model,the view have reference to VM but not the other way around)?
Thanks
|
|
|
|
|
Not really... Let's say you have three user controls; myControlA, myControlB, and myControlC. You have a MainPage with a tree view and a content control. The selection change on the tree view is passed back to the main view model via an ICommand just the same as a button or other view event.
The content control is bound to a content property on the view model which is implemented as a dependency property (required to support the bindings).
When a node is clicked on the tree view, the ICommand fires a method on the ViewModel. That method, in turn, creates an instance of myControlA and assigns it to the content property:
myContentProperty = new myControlA;
Because the content control's content property is bound to your content dependency property on the VM, it detects the change and updates the content presenter area with the new instance of myControlA. In your method to determine what gets loaded, you simply decide if you are creating an instance of myControlA, myControlB, myControlC, etc.
This doesn't break MVVM because we aren't creating a dependency on the user controls. You could, in fact, create a content object and assign the template xaml all in code then assign it to the content DP making it show on your form. In that case, the view doesn't even exist until runtime! If you took the view model and fired it up in a test harness, you would execute the ICommand and test to see that the content property gets set to the proper user control type. The fact you can do that demonstrates we didn't break MVVM.
The separation of concerns is to enable encapsulation and testing. Your view in this case is your main page and the VM is your main VM. You can't have a reference to the main view in your view model... that is a no-no... But creating a sub-view (which is itself encapsulated) is encouraged. In fact, if you look at the way App.xaml is setup, it does the same thing. Your app is actually rooted at app.xaml and mainpage.xaml is a sub-view of app.xaml.
The important thing, however, is to make sure that your sub views (the user controls) DO NOT have any bindings to the main view model. They should each bind to their own view models. While it isn't strictly against the rules to bind the sub view to the main view model, it makes it easier to keep things straight with the data contexts.
HTH!
|
|
|
|
|
|
I am new to silverlight MVVM technology. I am trying to creating an small app.
1.three textboxes which accept Ripee,Dollar,Pound.
2.When i entered any value to textbox, the other two textbox shold display corresponding currency .
|
|
|
|
|
You do this using data binding.
Bind properties to all three text boxes.
On the change of the first textbox, calculate currency and update properties attached to the other two textboxes.
|
|
|
|
|
can you please share some sample code.
|
|
|
|
|
|
|
thanks but still struggling for viewmodel
|
|
|
|
|
hi
i want using bordercolor animation
but i have many problem
To implement this, I spend a lot of time, but did not succeed.
when I put on the border, event does not occur , or
can not use the color property, or
changes in the text as far as border.
How one second over the border to change the color
of the animation could be used to
this is my failed my source
<Storyboard x:Key="MouseOver">
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="border" Storyboard.TargetProperty="BorderBrush.Color" >
<LinearColorKeyFrame KeyTime="00:00:1" Value="#FF4387FF"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Border x:Name="border />
<BeginStoryboard >
plz
help
me..
|
|
|
|
|
|
how to show data in combobox from database in silverlight
|
|
|
|
|
|
Fetch the data you need from the database via WCF and bind it to combo box.
|
|
|
|
|
|
I have a combobox column in a DataGrid.
I want the combo column's data source to be a list of LookupEntity called JobPhaseTypes on the VM:
public class LookupEntity
{
public int Id { get; set; }
public string Caption { get; set; }
}
The grid itself is bound to a list of JobPhase objects:
public class JobPhaseEntity : _BaseEntity
{
public int JobRevisionId { get; set; }
public string PhaseName { get; set; }
public LookupEntity JobPhaseType { get; set; }
public DateTime StartDateTime { get; set; }
public DateTime EndDateTime { get; set; }
}
}
So far I have this:
<DataGridComboBoxColumn Header="Phase Type"
SelectedItemBinding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.SelectedJobPhaseType}"
DisplayMemberPath="Caption"
Width="150">
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.JobPhaseTypes}"/>
<Setter Property="IsReadOnly" Value="True"/>
<Setter Property="StaysOpenOnEdit" Value="True" />
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.JobPhaseTypes}"/>
</Style>
</DataGridComboBoxColumn.ElementStyle>
</DataGridComboBoxColumn>
When I change the combo's value on any row, it changes on all rows.
What am I doing wrong here?
Many thanks
If it's not broken, fix it until it is
|
|
|
|
|
I am working with a datagrid with a combobox, and it took me 3 hours to get it working, and that's only after I stumbled across an example.
So now I have this:
<DataGrid Grid.Row="1"
Grid.Column="0"
ItemsSource="{Binding JobPhases}"
SelectedItem="{Binding SelectedJobPhase}"
SelectionMode="Single"
SelectionUnit="Cell"
CanUserAddRows="False"
CanUserReorderColumns="False"
CanUserResizeColumns="True"
CanUserResizeRows="False"
CanUserSortColumns="True"
AutoGenerateColumns="False"
AlternatingRowBackground="Gainsboro"
IsSynchronizedWithCurrentItem="True"
AlternationCount="2"
FontSize="12"
IsReadOnly="False"
FontWeight="Normal"
FontStyle="Normal">
<DataGrid.Columns>
<DataGridComboBoxColumn Header="Phase Type"
SelectedItemBinding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.SelectedJobPhaseType}"
DisplayMemberPath="Caption"
Width="150">
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.JobPhaseTypes}"/>
<Setter Property="IsReadOnly" Value="True"/>
<Setter Property="StaysOpenOnEdit" Value="True" />
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.JobPhaseTypes}"/>
</Style>
</DataGridComboBoxColumn.ElementStyle>
</DataGridComboBoxColumn>
</DataGrid.Columns>
</DataGrid>
The question I have is - can someone explain the syntax in the binding part?
What does 'RelativeSource' mean, and 'FindAncestor' and 'AncestorType'??
Many thanks!
If it's not broken, fix it until it is
|
|
|
|
|
I know this does not answer you question but it bears out our design decision to use dialogs. 3 hours faffing around trying to get a combo to work within a grid, 30 minutes to build a dialog, pop it and manage it. Hardest thing was finding a snippet to handle the double click on a grid which we did 3 years ago.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Actually, I agree with you. I normally use a dialog, but my client wants row editing.
If it's not broken, fix it until it is
|
|
|
|
|
Kevin Marois wrote: my client wants row editing
Bummer having to allow the client that level of say in the app design. Sorry I can't help.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
They pay the bills so they get what they want
If it's not broken, fix it until it is
|
|
|
|
|
|
Nice explanation. Thank you
If it's not broken, fix it until it is
|
|
|
|