我找到了很多这个问题的答案,但我似乎无法正确理解语法。考虑到解释here和我发现的许多其他人,我已经尝试了我能想到的每一个逻辑组合,但三周之后它仍然没有找到我。我只需要正确获取XAML的语法。
类:(为简单/保密而重命名)
UserControl1 - 包含三个全局列表,称为Streets,Houses和Cars
Street - 包含两个仅列出相关房屋和汽车的列表,名为MyHouses和MyCars
House - 在DataGrid中显示,其中一列是DataGridComboboxColumn,用于选择与此House关联的Street。在其中声明了一个名为Street的街道属性,以跟踪此情况并在get / set中执行其他计算。
Car - 在DataGrid中显示,其中一列是DataGridComboboxColumn,用于选择与此Car关联的Street。在其中声明了一个名为Street的街道属性,以跟踪此情况并在get / set中执行其他计算。
如果需要,我可以重构后面的代码以匹配上面的内容并发布。
XAML
<DataGrid ItemsSource="{Binding Streets, Mode=TwoWay}">
<DataGrid.Columns>
<DataGridTextColumn Header="Street" Binding="{Binding StreetID, Mode=TwoWay}"/>
</DataGrid.Columns>
</DataGrid>
<DataGrid ItemsSource="{Binding Cars, Mode=TwoWay}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding CarID, Mode=TwoWay}"/>
<DataGridComboBoxColumn
ItemsSource="{Binding Streets, RelativeSource={RelativeSource FindAncestor,AncestorType=UserControl1}, Mode=OneWay}"
SelectedItemBinding="{Binding Street}"
SelectedValue="{Binding StreetID}"
SelectedValuePath="StreetID"
DisplayMemberPath="StreetID">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding Streets, RelativeSource={RelativeSource FindAncestor,AncestorType=UserControl1}, Mode=OneWay}"/>
<Setter Property="IsReadOnly" Value="True"/>
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding Streets, RelativeSource={RelativeSource FindAncestor,AncestorType=UserControl1}, Mode=OneWay}"/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
</DataGrid.Columns>
</DataGrid>
<DataGrid ItemsSource="{Binding Houses, Mode=TwoWay}">
<!--copy of Cars with changed names-->
</DataGrid>
答案 0 :(得分:1)
如果我理解你正在尝试做的事情,我认为这就是你所追求的(基于你的描述中的模型):
请注意,由于我的模型,我的一些变量名称略有不同,例如UserControl
。
<DataGridComboBoxColumn
SelectedItemBinding="{Binding Street}"
DisplayMemberPath="StreetName">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding Streets, RelativeSource={RelativeSource FindAncestor,AncestorType=UserControl}, Mode=OneWay}"/>
<Setter Property="IsReadOnly" Value="True"/>
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding Streets, RelativeSource={RelativeSource FindAncestor,AncestorType=UserControl}, Mode=OneWay}"/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
对我来说,这会在数据网格中显示我的Cars
,其中包含所有相关列和可选择的街道(您可以以类似方式调整Houses
)。
正如我认为您已经阅读过,DataGridComboBoxColumn
对于解析其DataContext
有点奇怪。当您尝试将ItemsSource
设置在DataGridComboBoxColumn
的顶部时,会造成混淆。
这应该适用于您所描述的示例(我使用Cars
建模并且Houses
使用Street
对象作为跟踪属性,而不是ID)。
如果您决定要合并SelectedValue
并使用返回的Street
ID(在Car
和House
上存储为ID属性,我认为您将拥有用你的风格模板中的另一个setter来做。
修改强> 我使用的样机(在XAML中将Datacontext设置为self)。 N.B对象不会相互跟踪(因为我不确定你的设置是什么)。
public partial class UserControl1 : UserControl
{
public List<Street> Streets { get; set; }
public List<House> Houses { get; set; }
public List<Car> Cars { get; set; }
public UserControl1()
{
Streets = new List<Street>();
Houses = new List<House>();
Cars = new List<Car>();
Street streetOne = new Street() { StreetID = 1, Name = "Street One" };
Street streetTwo = new Street() { StreetID = 1, Name = "Street Two" };
Car carOne = new Car() { CarID = 1, Name = "KITT", MyStreet = streetOne };
Car carTwo = new Car() { CarID = 2, Name = "Car 2", MyStreet = streetTwo };
House houseOne = new House() { HouseID = 1, Name = "House 1", MyStreet = streetOne };
InitializeComponent();
streetOne.MyCars.Add(carOne);
streetOne.MyHouses.Add(houseOne);
streetTwo.MyCars.Add(carTwo);
Cars.Add(carOne);
Cars.Add(carTwo);
Houses.Add(houseOne);
Streets.Add(streetOne);
Streets.Add(streetTwo);
}
}
public class Car
{
public int CarID { get; set; }
public string Name { get; set; }
private Street _street;
public Street MyStreet
{
get { return this._street; }
set { this._street = value; }
}
}
public class House
{
public int HouseID { get; set; }
public string Name { get; set; }
public Street MyStreet { get; set; }
}
public class Street
{
public int StreetID { get; set; }
public string Name { get; set; }
public List<House> MyHouses { get; set; }
public List<Car> MyCars { get; set; }
public Street()
{
MyHouses = new List<House>();
MyCars = new List<Car>();
}
}
答案 1 :(得分:0)
尽管全局列表是ObservableCollections,但它们似乎不会在后面的代码构造函数中触发PropertyChangedEvents。我在添加内容之后在代码中设置了ItemsSource,它现在似乎工作正常。真正没有意义的是,一旦Streets出现在House和Car对象中,属性更改事件就会被触发,因为两者都知道彼此的变化。使用Chris在后面的代码中发布的设置工作,所以我将他的帖子标记为答案。我不知道为什么当只与XAML中的设置绑定时列表为空。