0

ビューモデルを使用するウィンドウがあります。この画面には、1つの画面に2つのリストビューが含まれています。最初のリストビューは、プロジェクトと呼ばれる私のビューモデルのプロパティにバインドされます。このプロパティは、次のようにモデルを返します

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; }
}

最初のリストビューには期待どおりにプロジェクト名が表示されますが、いずれかのアイテムをクリックしたときに、2番目のリストビューにprojectdetailsプロパティの詳細が表示されるようにしたいと思います。最初のアイテムがチャイルドリーンであることがほぼ機能しているように見えますが、最初のリストビューで選択したアイテムが変更されたことが通知されていないと思います。どうすればいいですか?私は何時間も髪を抜いてきたので、どんなアイデアでもいただければ幸いです!

これはxamlです

<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>

4

2 に答える 2

2

ビューモデルは(少なくとも)を実装する必要がありますINotifyPropertyChanged。これは、選択(または他のプロパティ)が変更され、バインディングを更新する必要がある場合にWPFが認識する方法です。

したがって、次のようなものが必要です。

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 Frameworkの将来のバージョンでは、「発信者情報」属性を使用すると、これがはるかに簡単になります(http://www.thomaslevesque.com/2012/06/13/using-c-5-caller-info-attributes-when -targeting-earlier-versions-of-the-net-framework /)。しかし、今日の時点で、これは通常それが行われる方法です。

アップデート

わかりました。コメントに基づいて、ListViewのSelectedItemプロパティをビューモデルのプロパティにバインドする必要があります。次に、2番目のListViewをそのプロパティにバインドすることもできます。このようなもの:

<ListView ... SelectedItem="{Binding Path=FirstListViewSelectedItem, Mode=TwoWay}" .. >

そして、2番目のリストビューは次のようになります。

<ListView ... ItemsSource="{Binding Path=FirstListViewSelectedItem.ProjectDetails, Mode=OneWay" .. />
于 2012-06-26T15:03:28.313 に答える
2

コードに現在の管理が表示されません。CollectionViewを使用すると、無料で入手できます。以下のサンプルを参照してください。

XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">

    <StackPanel>
        <ListBox ItemsSource="{Binding Path=ProjectsView}" DisplayMemberPath="Name" IsSynchronizedWithCurrentItem="True"/>
        <ListBox ItemsSource="{Binding Path=ProjectsView/ProjectDetails}" />
    </StackPanel>
</Window>

背後にあるコード:

using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            DataContext = new VM();
        }
    }

    public class VM
    {
        public VM()
        {
            List<Project> projectsModel = new List<Project>();
            projectsModel.Add(new Project("AAA"));
            projectsModel.Add(new Project("BBB"));
            projectsModel.Add(new Project("CCC"));

            ProjectsView = CollectionViewSource.GetDefaultView(projectsModel);
        }

        public ICollectionView ProjectsView { get; private set; }
    }

    public class Project
    {
        public Project(string name)
        {
            Name = name;
        }

        public string Name { get; private set; }
        public IEnumerable<string> ProjectDetails
        {
            get
            {
                for (int i = 0; i < 3; i++)
                {
                    yield return string.Format("{0}{1}", Name, i);
                }
            }
        }
    }
}
于 2012-06-26T16:19:03.670 に答える