私はお互いを指している2つの異なるオブジェクトを持っています。最初のオブジェクトは、会社内の部門を表します。そのオブジェクトには2つのコレクションがあります。従業員は部門内で働くすべての従業員であり、プロジェクトはその部門内で進行中の特別プロジェクトです。だから、最初のオブジェクトは、次のようになります。部門に新しいプロジェクトを追加するとき、私はこのようになり、そのプロジェクトへの分割、への参照を渡すことComboBox、ItemsSourceとSelectedValueを異なるソースにバインドすることは可能ですか?
public class Division : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
ObservableCollection<Employee> _employees;
ObservableCollection<Project> _projects;
public Division()
{
Employees = new ObservableCollection<Employee>();
Projects = new ObservableCollection<Project>();
}
public ObservableCollection<Employee> Employees
{
get { return _employees; }
set
{
if (_employees != value)
{
_employees = value;
PropertyChanged(this, new PropertyChangedEventArgs("Employees"));
}
}
}
public ObservableCollection<Project> Projects
{
get { return _projects; }
set
{
if (_projects != value)
{
_projects = value;
PropertyChanged(this, new PropertyChangedEventArgs("Projects"));
}
}
}
public void AddNewProject()
{
this.Projects.Add(new Project(this));
}
}
お知らせ:
public class Project : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
string _projectName;
DateTime _deadline = DateTime.Now;
Division _division;
ObservableCollection<Employee> _members;
public Project()
{
Members = new ObservableCollection<Employee>();
}
public Project(Division div)
{
Members = new ObservableCollection<Employee>();
Division = div;
}
public string ProjectName
{
get { return _projectName; }
set
{
if (_projectName != value)
{
_projectName = value;
PropertyChanged(this, new PropertyChangedEventArgs("ProjectName"));
}
}
}
public DateTime Deadline
{
get { return _deadline; }
set
{
if (_deadline != value)
{
_deadline = value;
PropertyChanged(this, new PropertyChangedEventArgs("Deadline"));
}
}
}
public Division Division
{
get { return _division; }
set
{
if (_division != value)
{
if (_division != null)
{
_division.Employees.CollectionChanged -= members_CollectionChanged;
}
_division = value;
if (_division != null)
{
_division.Employees.CollectionChanged += members_CollectionChanged;
}
PropertyChanged(this, new PropertyChangedEventArgs("Division"));
}
}
}
public ObservableCollection<Employee> Members
{
get { return _members; }
set
{
if (_members != value)
{
if (_members != null)
{
_members.CollectionChanged -= members_CollectionChanged;
}
_members = value;
if (_members != null)
{
_members.CollectionChanged += members_CollectionChanged;
}
PropertyChanged(this, new PropertyChangedEventArgs("Members"));
}
}
}
public ObservableCollection<Employee> AvailableEmployees
{
get
{
if (Division != null){
IEnumerable<Employee> availables =
from s in Division.Employees
where !Members.Contains(s)
select s;
return new ObservableCollection<Employee>(availables);
}
return new ObservableCollection<Employee>();
}
}
void members_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
PropertyChanged(this, new PropertyChangedEventArgs("AvailableEmployees"));
}
}
私がこれをやっている理由は、プロジェクトにはどんなタイプのチームも働くことができますが、部門内からだけです。したがって、部門のダッシュボードを構築する場合、マネージャはそのプロジェクトの従業員を選択できますが、すでに割り当てられている従業員を配置することはありません。したがって、プロジェクトオブジェクトのAvailableEmployeesプロパティは、常にそのプロジェクトに割り当てられていない人を追跡します。
私が抱えている問題は、これをUIに変換する方法です。このビューに関連付けられたビューモデルは以下のようである
<UserControl x:Class="Test.Views.TestView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
xmlns:local="clr-namespace:Test.Views"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel>
<ListBox ItemsSource="{Binding Div.Projects}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Background="Transparent"
BorderThickness="0, 0, 0, 2"
BorderBrush="Black"
Margin="0, 0, 0, 5"
Padding="0, 0, 0, 5">
<StackPanel>
<TextBox Text="{Binding ProjectName}"/>
<ListBox ItemsSource="{Binding Members}">
<ListBox.ItemTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=local:TestView}, Path=DataContext.AvailableEmployees}"
DisplayMemberPath="FirstName"
Text="{Binding FirstName}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content="Add Employee to Project"
Command="{Binding RelativeSource={RelativeSource AncestorType=local:TestView}, Path=DataContext.AddEmployeeToProject}"
CommandParameter="{Binding}"/>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content="Add New Project"
Command="{Binding AddNewProject}" />
</StackPanel>
:
public class TestViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private Division _div;
public TestViewModel(Division div)
{
Div = div;
AddNewProject = new DelegateCommand(OnAddNewProject);
AddEmployeeToProject = new DelegateCommand<Project>(OnAddEmployeeToProject);
}
public DelegateCommand AddNewProject { get; set; }
public DelegateCommand<Project> AddEmployeeToProject { get; set; }
public Division Div
{
get { return _div; }
set
{
if (_div != value)
{
_div = value;
PropertyChanged(this, new PropertyChangedEventArgs("Div"));
}
}
}
private void OnAddNewProject()
{
Div.AddNewProject();
}
private void OnAddEmployeeToProject(Project proj)
{
var availables = proj.AvailableEmployees;
if (availables.Count > 0)
{
proj.Members.Add(availables[0]);
}
}
}
しかし、私はそれぞれのコンボボックスを得ることができない私がこれまで行ってきた実験では、このようになります各プロジェクトの従業員が働きます。選択したアイテム/値がアイテムソースにバインドされているように見えますが、コンボボックスが空白になるたびに表示されます。私はこれをSelectedValueとSelectedItemプロパティでコンボボックスにもしようとしましたが、うまくいきませんでした。
どのようにしてこれら2つを分けますか。私がここで逃しているものは他にありますか?
おそらくOTですが、なぜDivを変更したときに 'PropertyChanged(" Class ")を呼びますか?また、「選択したアイテム/値がアイテムソースにバインドされているようです」という意味はどうですか?私はその文の意味を理解できません。 –
実際には、コード内のどこでも 'SelectedValue'を使って何もしません。 –
PropertyChangedの "クラス"は、(私がコードで行った以前の変更の)タイプミスです。それはPropertyChanged( "Div")でなければなりません。投稿で修正します。それは私のコメントになると、私はコンボボックスが毎回空白になる理由がわからないので、何が問題なのかちょうど推測しています。私はおそらく、コンボボックスのitemssourceがMembersコレクションに実際に入力された値に基づいて動的に変化するため、コンボボックスに実際に表示される値に影響を与えてしまうからです。 – user2921009