3

我已经找到了很多关于这个问题的答案,但我似乎无法正确使用语法。鉴于这里的解释以及我发现的许多其他解释,我已经尝试了所有我能想到的逻辑组合,但三周后我仍然无法理解。我只需要正确获取 XAML 的语法。

类:(为简单/保密而重命名)

UserControl1 - 包含三个全局列表,称为 Streets、Houses 和 Cars

Street - 包含两个仅关联的房屋和汽车的列表,称为 MyHouses 和 MyCars

House - 在 DataGrid 中显示,其中一列是 DataGridComboboxColumn,用于选择与此 House 关联的街道。在其中声明了一个名为 Street 的 Street 属性,以跟踪这一点并在 get/set 中进行其他计算。

Car - 在 DataGrid 中显示,其中一列是 DataGridComboboxColumn,用于选择此 Car 与哪条 Street 关联。在其中声明了一个名为 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>

4

2 回答 2

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对象作为跟踪属性,而不是 ID)。HousesStreet

如果您决定要合并SelectedValue并使用返回的StreetID(作为 ID 属性存储在Car和上House,我认为您必须使用样式模板中的另一个设置器来执行此操作。

编辑: 我使用的模型(Datacontext 在 XAML 中设置为 self)。注意对象不会相互跟踪(因为我不确定你有什么设置)。

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>();
    }
}
于 2013-07-31T23:10:41.437 回答
0

尽管全局列表是 ObservableCollections,但它们似乎并没有在后面代码的构造函数中触发 PropertyChangedEvents。添加内容后,我在后面的代码中设置了 ItemsSource,现在它似乎工作正常。真正没有意义的是,一旦 Streets 出现在 House 和 Car 对象中,就会触发属性更改事件,因为两者都知道彼此的更改。使用 Chris 在后面的代码中发布的设置有效,所以我将他的帖子标记为答案。我不知道为什么仅在 XAML 中与该设置绑定时列表为空。

于 2013-08-01T17:33:06.493 回答