emergency help needed

Jan 6, 2012 at 8:20 AM

as u know I am am big fan of this control but today I faced big problem. in my MVVM app I want to bind item select or click event to viewmodel command but can not find way. please help me to figure out how to make this work. this is very urgent as we have presentation and this is the only think making big problem for us.

Coordinator
Jan 13, 2012 at 2:10 PM
Edited Jan 13, 2012 at 2:21 PM

Sorry for the delayed response... for some reasons i didn't recieved the codeplex notification for the new discussion

This is the default view control created from the template project with expression blend
i added a navigation pane with two items, when selecting the first one the command get called as when you click on the button

the xaml

	<DockPanel x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource MainViewModelDataSource}}" d:DataContext="{d:DesignData /SampleData/MainViewModelSampleData.xaml}" >
		<s:NavigationPane x:Name="navigationPane" HorizontalAlignment="Left" Width="200">
			<i:Interaction.Triggers>
				<i:EventTrigger EventName="SelectionChanged">
					<i:Interaction.Behaviors>
						<ic:ConditionBehavior>
							<ic:ConditionalExpression>
								<ic:ComparisonCondition LeftOperand="{Binding SelectedIndex, ElementName=navigationPane}" RightOperand="0"/>
							</ic:ConditionalExpression>
						</ic:ConditionBehavior>
					</i:Interaction.Behaviors>
					<ic:CallMethodAction MethodName="ViewModelMethod" TargetObject="{Binding}"/>
				</i:EventTrigger>
			</i:Interaction.Triggers>
			<s:NavigationPaneItem Header="Update value on select" >
				<Grid/>
			</s:NavigationPaneItem>
			<s:NavigationPaneItem Header="No Command"></s:NavigationPaneItem>
		</s:NavigationPane>
		<Grid>
			<TextBlock Text="{Binding ViewModelProperty}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
			<Button Content="Update Value" Height="41" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,125,0,0">
				<i:Interaction.Triggers>
					<i:EventTrigger EventName="Click">
						<ic:CallMethodAction MethodName="ViewModelMethod" TargetObject="{Binding}"/>
					</i:EventTrigger>
				</i:Interaction.Triggers>
			</Button>
		</Grid>
	</DockPanel>

I do't know how much MVVM can be comparing the item selected to trigger the command call but is not possible put the code in the button, because the button ( navigation item ) is not a "button" rather an element of all the control, so the command should be triggered bu the control not the iktem button.
the same way.. should be the navigationpane control to decide which item trigger which command

hope this help
feel free to ask clarifications

0xfefi

Jan 13, 2012 at 6:07 PM

OK I will give a try to this XAML. the reason I want to achieve this scenario is same behavior as outlook has. If you select navigation panel item in outlook right side (lest call it main region) is changed. I am using PRISM 4 as app framework for current project and as it has navigation framework what I am tying to achieve is when one selects navigation panel item navigation request is triggered in appropriate viewmodel which asks prism navigation framework to navigate to cores corresponding view and will load it into the main region. in my app each navigation item is part of separate module an are automatically injected as modul is loaded in main application.

Jan 24, 2012 at 7:28 PM

This seems to be some sort of solution but if we say that each item is loaded by module and we want to navigate to modules dashboard when item is selected in this situation I thin I need to have solution to raise navigation request. this behavior is very similar to Microsoft Outlook when u select contacts or inbox main content area is changed and in my situation this main are will be filled from module which listen for particular event so it injects its main view in content region

Coordinator
Jan 25, 2012 at 9:17 AM

Hi taicodev, i think the solution is not in the events.. rather in databinding.

I had a hd crash lately and backing up files i found the original project for which the control was made.
There I had solved the problem using MEF and datababinding, and implementing a sot of servicing for the navigationpaneitems handling.
All items were defined in separate assemblies, and where responsible to notify the Shell ( main window ) of their activity.. as: "I'm selected please set this pane on the left". This is achieved having in the main form a contentcontrol which contents are binded to a property, when ever the property changes the contentcontrol contents changes too.

Since it was part of a more complex system... i'm cleaning it to create simple example project. I'll upload that soon in the repository.


Feb 14, 2012 at 12:29 AM

Hallo again. Could u show sample solution for this? The way u implemented navigation seems completely acceptable for me. I am exactly trying to implement this notification procedure but in my case central service will be called with parameter where to navigate in shells' main content region. Pleas note that I am using PRISM so there is a lots of flexibility in navigation. for now I think of creating custom behavior or attached property for this but I will wait till your suggestion and hope to get this work finally.

Coordinator
Feb 14, 2012 at 4:06 PM

Hi Taico dev, i finally did the example. I'm a bit busy lately, so i couldn't make it earlier.
You could find it in the downloads section ( http://navigationpane.codeplex.com/releases/62476/download/342274 )

There are 3 projects in the solution:
1. The application
2. A commondll ( a custom component project )
3. A Module dll which exports 2 navigationpaneitems with associated view contorol.

Essentially there in the common dll there are all the definitions of services interfaces and classes ( including a NavigationService definition )
The application then implements the Navigation iterface in its hown class.
The Module simply esports some classes with MEF, so if dll is present when application is started classes are loaded by the aplication.

The change of contents in the mainwindow ( Shell.xaml ) is done by binding to properties of the NavigationService. These property use INotifyPropertyChanged, so any time a property get changed from the service, the update of the main window get trigered by the binding:
NavigationPane->Items to NavigationService List loaded from MEF
ViewContent->Active navigationpane view content

I'm not that good in explaining my procedure... isn'it ! :)
But I hope this could give you an idea of how i solved the problem in my app.

All the trick is done in the NavigationService Class implemented by the Application.

This example may be a bit messed up, with classes and definitions not really used. I tried to clean it up, but this is an adaptation of a more complex project, which was interfacing with a Ribbon ( Tabs, Backstage )... so something may be still there.

Hope this is not too messed up !
If any question please feel free to ask.

0xfefi

Feb 14, 2012 at 9:52 PM
Edited Feb 14, 2012 at 9:58 PM

0xfefi I downloaded and looked through your sample application and would like to note that it is very interesting approach, but it is little bit complicated as well. At the moment I am developing and and redesigning this control a little bit so here is what I am about to do.

As u have Dependency property IsSelected I will tweak this section of code little so it will be able to have OnSelected dependency property and users will be able to bind it to their viewmodels.

 

public bool IsSelected
  {
   get { return (bool)GetValue(IsSelectedProperty); }
   set { SetValue(IsSelectedProperty, value); }
  }
  public static readonly DependencyProperty IsSelectedProperty =
    Selector.IsSelectedProperty.AddOwner(typeof(NavigationPaneItem), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Journal | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.AffectsParentMeasure, new PropertyChangedCallback(OnIsSelectedChanged)));

  private static void OnIsSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  {
   NavigationPaneItem item = d as NavigationPaneItem;
    
   if ((bool)e.NewValue)
   {
    NavigationPane nav = item.navigationPane; // item.Parent as NavigationPane;
    if (nav != null)
    {
     NavigationPaneItem selItem = (nav.SelectedItem is NavigationPaneItem ? nav.SelectedItem :
      nav.ItemContainerGenerator.ContainerFromItem(nav.SelectedItem)) as NavigationPaneItem;
     if (selItem != null && selItem != item)
       (selItem as NavigationPaneItem).IsSelected = false;
    }
    item.ChangeSelected(true);
   }
   else
    item.ChangeSelected(false);
  }

 

Another approache will be to create interaction behavior for interactivity to atache this behavior for item, but in this case  developers will be forced to reference extra assemblies.

veri interesting method here is ChangeSelected this is where I will chek for ICommand dependency property and if it is not null I will execute it

Apr 19, 2012 at 2:38 PM

I tried to modify your source but at the and I thought it is not good idea to modify library each time as new functionality is lacquered. Could u pleas modify it an a way that it has selected item property so we could bind its selected item directly to viewmodel or add OnSelectedItemChaned which would take ICommand as its' parameter?

Coordinator
Apr 19, 2012 at 6:15 PM

Hi taico dev
in fact it is already present.
Since the control derives from the Selector  class it has also the SelectedItem and SelectedValue Dependency Properties
The Control also has a SelectionChanged Event implemented which is fired any time the selected item changes.

I also just implemented ICommand support for NavigationPaneItem making it a ICommandSource
Avaiable on the latest change set in source control
The command if set is executed when the item becomes the selected item

Hope this helps

Apr 19, 2012 at 8:22 PM

Oh Thank u for your replay I think I have to grab latest source right now. u sad u already implemented this on NavigationPaneItem, but generally it might bring as to some boilerplate (in my case this will be exactly in this way). Let me shortly explain my solution for loading appropriate view in main content placeholder.

First of all I created custom attribute which is assigned to each NavigationPaneItem view (views are single usercontrols in my scenario as they are spread across multiply modules and are constructed and loaded during bootstrapping process) I have an event aggregator pattern and what I would like to to is to completely separate loading of content from NavigationPaneItem or its viewmodel so for this in my project each NavigationPaneItem code-behind file is decorated with attribute like this

[AssociatedView(typeof(StaffDashboard))]
StaffManagmentSection : NavigationPaneItem


If only I could have ability to bind ICommand to NavPanel itself it would be easier to implement this so whenever itm is selected Navpanel would invoke my command which is inside my infrastructure and inside this command I would read attribute from item and navigate to the view.

I think is easy one of the good approaches among many others and fits well with separation of concerns.

Dec 10, 2012 at 11:09 AM

Hello 0xfefi ,

I downloaded your example code from http://navigationpane.codeplex.com/releases/62476/download/342274 ).

I am finding difficulty in showing different page in right side dock panel.

Can you please help me. waiting for your response.

 

Thanks and Best regards,

Eln39

        

Coordinator
Dec 11, 2012 at 1:53 PM
eln39 wrote:

Hello 0xfefi ,

I downloaded your example code from http://navigationpane.codeplex.com/releases/62476/download/342274 ).

I am finding difficulty in showing different page in right side dock panel.

Can you please help me. waiting for your response.

 

Thanks and Best regards,

Eln39

        

Hi Eln39

What kind of difficulties are you having ?
Are you using the code with MEF example as basis ?

Dec 14, 2012 at 9:28 AM

Hello 0xfefi ,

 

Can you add sample code for switching different pages on right side when user clicks on left hand side button.

You can send me that code on eln39@rediffmail.com

 

Thanks and Best regards,

Eln39