ItemsSource 到 TreeView 的 SelectedItem 的 属性
ItemsSource to property of SelectedItem of TreeView
我正在创建我的第一个 WPF 应用程序(之前用 WinForms 做过一些),我开始喜欢它了(即使它有时会增加不必要的复杂性..)。
但是我遇到了一个我无法真正弄清楚的问题。
问题:
我有一个 TreeView 和一个带有所选(第二级)项目属性的伴随 GroupBox。这些属性在 TextBoxes 中是可编辑的(绑定到 SelectedItem.[属性])并且工作正常。
但是其中一个属性是一个列表(定义为 ObservableCollection),我想在 ComboBox 中显示它,所以我将 ItemsSource 绑定到 TreeView 的 SelectedItem.Modes:
<ComboBox Name="FixtureModesListBox" ItemsSource="{Binding ElementName=FixturesTreeView, Path=SelectedItem.Modes}" ItemTemplate="{StaticResource FixtureModeTemplate}" />
这显然不起作用,我得到的错误是:
BindingExpression path error: 'Modes' property not found on 'object' ''efcFixtureModel' ...
属性确实存在,被设置,是public等
我目前的解决方案
我可以通过使用一些代码隐藏(并引用完全相同的 "path")来让它工作:
private void FixturesTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
if (FixturesTreeView.SelectedItem is efcFixtureModel) // The 1st level/parent items is of a different type
{
FixtureModesListBox.ItemsSource = (FixturesTreeView.SelectedItem as efcFixtureModel).Modes;
}
}
我想不通为什么这不起作用,而且我在网上找不到任何好的信息。
编辑以包含更多信息:
<TreeView Name="FixturesTreeView" ItemTemplate="{StaticResource FixtureItemTemplate}" SelectedItemChanged="FixturesTreeView_SelectedItemChanged">
</TreeView>
...
// Assignment of ItemsSource
FixturesTreeView.ItemsSource = mainWin.Companies;
...
public partial class efcMainWindow : Window
{
// Definition of Companies
public ObservableCollection<efcCompany> Companies;
...
// Definition of efcCompany
public class efcCompany
{
public int Id { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public string Logo { get; set; }
public int FixtureCount { get { return Fixtures.Count; } }
public ObservableCollection<efcFixtureModel> Fixtures { get; set; }
public efcCompany(string name = "", int id = -1, string url = "", string logo = "")
{
this.Name = name;
this.Id = id;
this.Url = url;
this.Logo = logo;
this.Fixtures = new ObservableCollection<efcFixtureModel>();
}
public override string ToString()
{
return "#" + Id.ToString() + ": " + Name + " (" + Url + ", " + Logo + ")";
}
}
// Definition of efcFixtureController
public class efcFixtureModel
{
public int Id { get; set; }
public int Manufacturer { get; set; }
public efcFixtureType Type { get; set; }
public string Name { get; set; }
public string Image { get; set; }
public string Description { get; set; }
public byte TotalChannelCount { get; set; }
public ObservableCollection<efcFixtureMode> Modes;
public efcFixtureModel()
{
Modes = new ObservableCollection<efcFixtureMode>();
}
public override string ToString()
{
return "#" + Id.ToString() + ": " + Name + " (" + Type.ToString() + ", " + Image + ", " + Description + ")";
}
}
您需要将 efcFixtureModel.Modes 从 Field 转换为 属性:
public ObservableCollection<efcFixtureMode> Modes { get; set; }
请阅读What is Difference between Property and Variable in C#
正如我之前所说,您需要将 FixturesTreeView 中的 SelectedItem 绑定到 ViewModel 中类型为 efcFixtureModel 的 属性。
<TreeView Name="FixturesTreeView" ItemTemplate="{StaticResource FixtureItemTemplate}" SelectedItemChanged="FixturesTreeView_SelectedItemChanged"
SelectedItem="{Binding TreeViewSelectedItem}">
</TreeView>
<ComboBox Name="FixtureModesListBox" ItemsSource="{Binding TreeViewSelectedItem.Modes}" ItemTemplate="{StaticResource FixtureModeTemplate}" />
我正在创建我的第一个 WPF 应用程序(之前用 WinForms 做过一些),我开始喜欢它了(即使它有时会增加不必要的复杂性..)。 但是我遇到了一个我无法真正弄清楚的问题。
问题: 我有一个 TreeView 和一个带有所选(第二级)项目属性的伴随 GroupBox。这些属性在 TextBoxes 中是可编辑的(绑定到 SelectedItem.[属性])并且工作正常。 但是其中一个属性是一个列表(定义为 ObservableCollection),我想在 ComboBox 中显示它,所以我将 ItemsSource 绑定到 TreeView 的 SelectedItem.Modes:
<ComboBox Name="FixtureModesListBox" ItemsSource="{Binding ElementName=FixturesTreeView, Path=SelectedItem.Modes}" ItemTemplate="{StaticResource FixtureModeTemplate}" />
这显然不起作用,我得到的错误是:
BindingExpression path error: 'Modes' property not found on 'object' ''efcFixtureModel' ...
属性确实存在,被设置,是public等
我目前的解决方案 我可以通过使用一些代码隐藏(并引用完全相同的 "path")来让它工作:
private void FixturesTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
if (FixturesTreeView.SelectedItem is efcFixtureModel) // The 1st level/parent items is of a different type
{
FixtureModesListBox.ItemsSource = (FixturesTreeView.SelectedItem as efcFixtureModel).Modes;
}
}
我想不通为什么这不起作用,而且我在网上找不到任何好的信息。
编辑以包含更多信息:
<TreeView Name="FixturesTreeView" ItemTemplate="{StaticResource FixtureItemTemplate}" SelectedItemChanged="FixturesTreeView_SelectedItemChanged">
</TreeView>
...
// Assignment of ItemsSource
FixturesTreeView.ItemsSource = mainWin.Companies;
...
public partial class efcMainWindow : Window
{
// Definition of Companies
public ObservableCollection<efcCompany> Companies;
...
// Definition of efcCompany
public class efcCompany
{
public int Id { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public string Logo { get; set; }
public int FixtureCount { get { return Fixtures.Count; } }
public ObservableCollection<efcFixtureModel> Fixtures { get; set; }
public efcCompany(string name = "", int id = -1, string url = "", string logo = "")
{
this.Name = name;
this.Id = id;
this.Url = url;
this.Logo = logo;
this.Fixtures = new ObservableCollection<efcFixtureModel>();
}
public override string ToString()
{
return "#" + Id.ToString() + ": " + Name + " (" + Url + ", " + Logo + ")";
}
}
// Definition of efcFixtureController
public class efcFixtureModel
{
public int Id { get; set; }
public int Manufacturer { get; set; }
public efcFixtureType Type { get; set; }
public string Name { get; set; }
public string Image { get; set; }
public string Description { get; set; }
public byte TotalChannelCount { get; set; }
public ObservableCollection<efcFixtureMode> Modes;
public efcFixtureModel()
{
Modes = new ObservableCollection<efcFixtureMode>();
}
public override string ToString()
{
return "#" + Id.ToString() + ": " + Name + " (" + Type.ToString() + ", " + Image + ", " + Description + ")";
}
}
您需要将 efcFixtureModel.Modes 从 Field 转换为 属性:
public ObservableCollection<efcFixtureMode> Modes { get; set; }
请阅读What is Difference between Property and Variable in C#
正如我之前所说,您需要将 FixturesTreeView 中的 SelectedItem 绑定到 ViewModel 中类型为 efcFixtureModel 的 属性。
<TreeView Name="FixturesTreeView" ItemTemplate="{StaticResource FixtureItemTemplate}" SelectedItemChanged="FixturesTreeView_SelectedItemChanged"
SelectedItem="{Binding TreeViewSelectedItem}">
</TreeView>
<ComboBox Name="FixtureModesListBox" ItemsSource="{Binding TreeViewSelectedItem.Modes}" ItemTemplate="{StaticResource FixtureModeTemplate}" />