BindingExpression Path Error - 如何在MVVM模型中构造代码?

时间:2014-12-27 05:09:07

标签: c# wpf mvvm binding

我有一个Button,点击后应调整两个Widths的{​​{1}}。

Grids

<DataTemplate x:Key="ItemTemplate"> <DockPanel Width="Auto"> <Button Click="SelectMovie_Click" DockPanel.Dock="Top"> <Button.Template> <ControlTemplate > <Image Source="{Binding image}"/> </ControlTemplate> </Button.Template> <i:Interaction.Behaviors> <local:UniqueNameBehavior ID="{Binding id}"/> </i:Interaction.Behaviors> <i:Interaction.Triggers> <i:EventTrigger EventName="MouseLeftButtonDown"> <i:InvokeCommandAction Command="{Binding ShowRightGridCommand}"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> <TextBlock Text="{Binding title}" HorizontalAlignment="Center" DockPanel.Dock="Bottom"/> </DockPanel> </DataTemplate> 显示在Button内:

Grid

<Grid Grid.Row="2" > <Grid.ColumnDefinitions> <ColumnDefinition Width="{Binding LeftGridWidth}" /> <ColumnDefinition Width="{Binding RightGridWidth}" /> </Grid.ColumnDefinitions> // BUTTONS DISPLAYED HERE <Grid x:Name="LeftGrid" Grid.Row="2" Grid.Column="0" > <Border BorderThickness="1" BorderBrush="Red"> <ItemsControl ItemTemplate="{StaticResource ItemTemplate}" ItemsSource="{Binding _movies}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <UniformGrid Columns="5" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl> </Border> </Grid> <Grid x:Name="RightGrid" HorizontalAlignment="Left" Grid.Row="2" Grid.Column="1" > <DockPanel> <StackPanel VerticalAlignment="Top" Height="200"> <TextBlock Width="200" Height="50" DockPanel.Dock="Top" HorizontalAlignment="Left"> <TextBlock.Text> <MultiBinding StringFormat="{}{0} ({1})"> <Binding Path = "SelectedMovie.title"/> <Binding Path = "SelectedMovie.year"/> </MultiBinding> </TextBlock.Text> </TextBlock> </StackPanel> <StackPanel VerticalAlignment="Top" Height="200"> <Grid HorizontalAlignment="Center"> <Image Source="star_icon.png" Width="100" Height="100" VerticalAlignment="Top"/> <TextBlock Text="{Binding SelectedMovie.rating}" Style="{StaticResource AnnotationStyle}" Width="150"/> </Grid> </StackPanel> </DockPanel> </Grid> </Grid>

ViewModel

问题是当我运行我的代码时,我收到错误:

public List<MediaDetail> _movies { get; set; }
    public string selectedMovieID { get; set; }

    private GridLength _leftGridWidth;
    private GridLength _rightGridWidth;
    private readonly GridLength _defaultRightGridWidth = new GridLength(0, GridUnitType.Pixel);


    public MoviePanelViewModel()
    {
        ShowRightGridCommand = new DelegateCommand(SwitchRightGridWidth);
        LeftGridWidth = new GridLength(7, GridUnitType.Star);
        RightGridWidth = _defaultRightGridWidth;
    }

    private void SwitchRightGridWidth()
    {
        RightGridWidth = RightGridWidth == _defaultRightGridWidth ? new GridLength(3, GridUnitType.Star) : _defaultRightGridWidth;
    }

    public GridLength LeftGridWidth
    {
        get { return _leftGridWidth; }
        set { _leftGridWidth = value; OnPropertyChanged("LeftGridWidth"); }
    }


    public GridLength RightGridWidth
    {
        get { return _rightGridWidth; }
        set { _rightGridWidth = value; OnPropertyChanged("RightGridWidth"); }
    }

    public ICommand ShowRightGridCommand { get; set; }

我不确定如何构建我的代码,以便BindingExpression path error: 'ShowRightGridCommand' property not found on 'object' ''MediaDetail' 的{​​{1}}属性可以保留在Width中,Grids可以保留在我的ViewModel中也有效。我Trigger的{​​{1}}是Button

有没有很好的方法来实现这一目标?

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

问题是你在DataTemplate中的绑定:WPF尝试在MediaDetail类上找到属性路径ShowRightGridCommand,因为ItemsControl将它生成的每个项容器的数据上下文设置为相应的项。

您真正想要做的是绑定到视图模型。你可以这样做:

{Binding ElementName=LeftGrid, Path=DataContext.ShowRightGridCommand}

LeftGrid是ItemsControl之外的元素。它的DataContext是您的MoviePanelViewModel实例,并且定义了您的ShowRightGridCommand属性。

更清洁的是将名称root放在视图的根控件(通常是UserControl或Window)上,然后使用ElementName=root,Path=DataContext....作为绑定 - 至少这是我通常所做的。

另一种方法是使用RelativeSource={RelativeSource UserControl},但我发现ElementName=root更简单。