2016-01-12 51 views
0

我有一个应用程序有一个导航菜单,使用命令去页面。绑定到ViewModel无法使用RelativeSource

导航菜单已经在XAML中创建和我把它保存在Navigation.xaml见下文

<ResourceDictionary 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:vm="clr-namespace:Cirdan.Wpf.Navigation" 
xmlns:infrastructure="clr-namespace:Cirdan.Wpf.Infrastructure"> 

<ResourceDictionary.MergedDictionaries> 
    <ResourceDictionary Source="/Cirdan.Wpf;component/Resources/Styles/Stylesheet.xaml" /> 
</ResourceDictionary.MergedDictionaries> 

<DataTemplate x:Key="Navigation" >   
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="4*"/> 
      <RowDefinition Height="*"/> 
     </Grid.RowDefinitions> 
     <UniformGrid Grid.Row="0" Columns="1"> 
      <Button DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type vm:NavigationViewModelBase}}}" Visibility="{Binding ElementName=Menu, Path=IsChecked, Converter={StaticResource VisibilityConverter}}" Command="{Binding ViewerPageCmd}" >Viewer Screen</Button> 
      <Button DataContext="{Binding NavigationViewModel, Source={x:Static infrastructure:MainWindow.LocatorX}}" Visibility="{Binding ElementName=Menu, Path=IsChecked, Converter={StaticResource VisibilityConverter}}" Command="{Binding}" >Acquisition Screen</Button> 
      <Button DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type vm:NavigationViewModelBase}}}" Visibility="{Binding ElementName=Menu, Path=IsChecked, Converter={StaticResource VisibilityConverter}}" Command="{Binding WorklistPageCmd}" >Worklist Screen</Button> 
     </UniformGrid> 
     <ToggleButton Grid.Row="1" Style="{StaticResource ToggleBtnToolStyle}" x:Name="Menu" IsChecked="true" Background="Transparent" BorderThickness="0" > 
      <StackPanel Orientation="Horizontal"> 
       <ContentPresenter Margin="5" Height="50" Content="{StaticResource MenuIcon}"></ContentPresenter> 
       <Viewbox> 
        <TextBlock Margin="5" Style="{StaticResource TxtToolStyle}">Menu</TextBlock> 
       </Viewbox> 
      </StackPanel> 
     </ToggleButton> 
    </Grid> 
</DataTemplate> 

,我想要绑定这些按钮的视图模型命令到被称为NavigationViewModelBase。 CS

using GalaSoft.MvvmLight; 
using GalaSoft.MvvmLight.Command; 
using GalaSoft.MvvmLight.Messaging; 

namespace Cirdan.Wpf.Navigation 
{ 
public abstract class NavigationViewModelBase : ViewModelBase 
{ 
    private List<DicomMetadataModel> _dicomMetadata; 

    //Navigation Cmd 
    public ICommand AcquisitionPageCmd { get; private set; } 
    public ICommand ManualEntryWindowCmd { get; private set; } 
    public ICommand SessionWindowCmd { get; private set; } 
    public ICommand SettingsWindowCmd { get; private set; } 
    public ICommand StudyInfoPageCommandCmd { get; private set; } 
    public ICommand ViewerPageCmd { get; private set; } 
    public ICommand WorklistPageCmd { get; private set; } 


    protected NavigationViewModelBase() 
    { 
     AcquisitionPageCmd = new RelayCommand(() => Messenger.Default.Send(new GoToPageMessage(Pages.AcquisitionScreen))); 
     ManualEntryWindowCmd = new RelayCommand(() => Messenger.Default.Send(new ShowDialogMessage(Pages.ManualEntry, DicomMetadata))); 
     SessionWindowCmd = new RelayCommand(() => Messenger.Default.Send(new ShowDialogMessage(Pages.Session))); 
     SettingsWindowCmd = new RelayCommand(() => Messenger.Default.Send(new ShowDialogMessage(Pages.Settings))); 
     ViewerPageCmd = new RelayCommand(() => Messenger.Default.Send(new GoToPageMessage(Pages.Viewer))); 
     WorklistPageCmd = new RelayCommand(() => Messenger.Default.Send(new GoToPageMessage(Pages.Worklist))); 
    } 
} 
} 

在每一页上,然后我用下面的代码添加导航

<ContentControl Grid.Column="2" Grid.Row="2" ContentTemplate="{StaticResource Navigation }" /> 

此刻我没有收到任何错误,并且当我在上面的一个按钮中设置了DataContext时,当我去绑定我的命令时,我可以看到该Viewmodel的所有属性,正常工作,但是当我运行该程序并单击这些按钮时,什么都没有发生。

感谢所有帮助

+0

从代码中的所有3个按钮中删除DataContext,并告诉发生了什么。 – AnjumSKhan

回答

1

祖先绑定会为元素的VisualTree /视图仅工作或简单地在你的页面elemnts。 viewModel不在页面的任何地方作为控件。因此,取代viewModel给视图的类型具有NavigationViewModelBase作为datacontext.write绑定如下(如果您的视图/控制是NavigationView绑定将)。在路径写的财产VM:NavigationViewModelBase 类:

<Button DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type v:NavigationView}}, path= PropertyYouWantToBind}" 

只是确保你有没有在层次中的任何其他控件定义的DataContext,按钮会越来越相同的DataContext的观点,那么你只需必须绑定命令。你已经正确地完成了。

如果你还没有给你的视图中的任何控件的DataContext然后只是给你contentControl或网格。就像

<Grid> 
    <Grid.DataContext> 
     <vm:NavigationViewModelBase /> 
    </Grid.DataContext> 
<Grid.RowDef....... 

然后用简单的绑定命令。

1

的RelativeSource FindAncestor会在祖先的VisualTree。

的VisualTree可以关注一下:

Window 
    Grid 
     TextBlock 
     TextBox 
     Button 

的ViewModels不是视觉3

对于按钮的例子祖先是电网和窗口在这种情况下。

那该怎么做呢?

好吧,在ResourceDictionary中创建自定义UserControl而不是ContentControl与ContentTemplate。

在usercontrol中将DataContext设置为继承自NavigationViewModelBase的类。

然后结合将是简单的:

<UniformGrid Grid.Row="0" Columns="1"> 
     <Button Command="{Binding ViewerPageCmd}">Viewer Screen</Button> 
     <Button Command="{Binding AcquisitionPageCmd}">Acquisition Screen</Button> 
     <Button Command="{Binding WorklistPageCmd}" >Worklist Screen</Button> 
    </UniformGrid> 
+0

是否有可能实现我正在尝试做的事情,或者我该怎么做?对不起,我有点失落与绑定。 –

+0

如果您在Bindings中迷路了,请停止执行您的操作并查找一些WPF教程。创建新的hello world项目并在那里绑定。如果你不明白绑定是如何工作的,你将无法在wpf中做任何事情。 – Liero