wpf - 在 WPF ListView 中选择项目时,更新其他控件以查看详细信息

标签 wpf data-binding mvvm

我有一个使用 View 模型的窗口。此屏幕在一个屏幕上包含 2 个 ListView 。第一个 ListView 绑定(bind)到我的 View 模型上名为项目的属性。该属性返回一个模型如下

class ProjectsModel
{
    public string ProjectName { get; set; }
    public ObservableCollection<ProjectModel> ProjectDetails { get; set; }
}

在此类中,ProjectModel 如下所示
public class ProjectModel
{
    public string ProjectName { get; set; }
    public string ProjectId { get; set; }
    public string ProjectFileId { get; set; }
    public string ProjectSource { get; set; }
    public string ClientCode { get; set; }
    public string JobNumber { get; set; }
}

第一个 ListView 按我的预期显示项目名称,但我希望这样当我单击任何项​​目时,第二个 ListView 应显示其 projectdetails 属性的详细信息。它几乎似乎可以工作,它显示了第一个子项,但我相信它没有被告知第一个 ListView 的选定项目已更改。我可以这样做吗?任何想法都将不胜感激,因为我已经把头发拉了几个小时了!

这是xml
<Window x:Class="TranslationProjectBrowser.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:TranslationProjectBrowser.ViewModels"
    xmlns:local="clr-namespace:TranslationProjectBrowser.Models"
    Title="MainWindow" Height="373" Width="452" Background="LightGray">
<Window.DataContext>
    <vm:ProjectBrowserViewModel></vm:ProjectBrowserViewModel>
</Window.DataContext>
<Window.Resources>
    <ObjectDataProvider x:Key="projectList" ObjectType="{x:Type vm:ProjectBrowserViewModel}" />
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource projectList}}">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="176*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="176*" />
        <RowDefinition Height="254*" />
    </Grid.RowDefinitions>
    <DockPanel LastChildFill="True" >
        <TextBlock DockPanel.Dock="Top" Text="Projects" Margin="5,2"></TextBlock>
        <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
        <TextBox Name="ProjectName" Width="140" Margin="5,2" Height="18" FontFamily="Calibri" FontSize="10"></TextBox>
        <Button Height="18" Width="45" HorizontalAlignment="Left" Margin="0,2" FontSize="10" Content="Add" Command="{Binding Path=AddProject}" CommandParameter="{Binding ElementName=ProjectName, Path=Text}"></Button>
        <TextBlock Text="{Binding Path=ErrorText}" VerticalAlignment="Center" Margin="6,2" Foreground="DarkRed"></TextBlock>
        </StackPanel>
        <ListView Name="project" HorizontalAlignment="Stretch" Margin="2" ItemsSource="{Binding Path=Projects}" IsSynchronizedWithCurrentItem="True">
            <ListView.View>
                <GridView>
                    <GridViewColumn DisplayMemberBinding="{Binding Path=ProjectName}" Header="Name" Width="200" />
                </GridView>
            </ListView.View>
        </ListView>
    </DockPanel>
    <DockPanel LastChildFill="True" Grid.Row="1" >
        <TextBlock DockPanel.Dock="Top" Text="Project Files" Margin="5,2"></TextBlock>
        <ListView  HorizontalAlignment="Stretch" Margin="2" ItemsSource="{Binding Path=Projects/ProjectDetails}" IsSynchronizedWithCurrentItem="True" >
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=ProjectName}"  Width="200" />
                    <GridViewColumn Header="Job Number" DisplayMemberBinding="{Binding Path=JobNumber}" Width="100" />
                </GridView>
            </ListView.View>
        </ListView>
    </DockPanel>
</Grid>

最佳答案

你的 View 模型应该(至少)实现 INotifyPropertyChanged .这就是 WPF 将如何知道您的选择(或其他属性)何时更改以及需要更新绑定(bind)的方式。

所以你应该有这样的东西:

class ProjectsModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String PropertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
        }
    }

    public string ProjectName 
    { 
        get
        {
            return _projectName;
        }
        set
        {
            _projectName = value;
            NotifyPropertyChanged("ProjectName");
        }       
    }
    public ObservableCollection<ProjectModel> ProjectDetails 
    { 
        get
        {
            return _projectDetails;
        }
        set
        {
            _projectDetails = value;
            NotifyPropertyChanged("ProjectDetails");
        }
    }
}

在 .NET 框架的 future 版本中,使用“调用者信息”属性(http://www.thomaslevesque.com/2012/06/13/using-c-5-caller-info-attributes-when -targeting-earlier-versions-of-the-net-framework/)。但截至今天,这通常是如何完成的。

更新

好的,所以根据您的评论,您需要绑定(bind) ListView 的 SelectedItem属性到 View 模型上的属性。然后,您也可以将第二个 ListView 绑定(bind)到该属性。像这样的东西:
<ListView ... SelectedItem="{Binding Path=FirstListViewSelectedItem, Mode=TwoWay}" .. >

然后你的第二个 ListView 将是这样的:
<ListView ... ItemsSource="{Binding Path=FirstListViewSelectedItem.ProjectDetails, Mode=OneWay" .. />

关于wpf - 在 WPF ListView 中选择项目时,更新其他控件以查看详细信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11210190/

相关文章:

c# - 动态添加点击事件

c# - ASP.NET 中的 List<T> 和 ListViews 的 Dictionary<T>

c# - 将对象列表数据绑定(bind)到 WinForms DataGridView,但不显示某些公共(public)属性

c# - 打印多页xaml控件

c# - 为什么我的 WPF ListView/GridView 没有虚拟化?

c# - 虚拟机的 UWP MVVM 数据绑定(bind)(来自字符串的 textbox.text)

mvvm - 初始化 View 模型

c# - 使用 MVVM 处理用户设置

wpf - 什么是好的 WPF 网格控件?

wpf - 如何在 XAML 中设置 ComboBox DataContext?