2013-07-31 3 views
2

Я нашел много ответов на этот вопрос, но я не могу получить синтаксис правильно. Я пробовал каждую логическую комбинацию, о которой я могу думать, учитывая объяснение here и многие другие, которые я нашел, но это все еще ускользало от меня через три недели. Мне просто нужно получить синтаксис права XAML.Что не так с этим синтаксисом привязки DataGridComboBoxColumn?

Классы: (переименовываются для простоты/конфиденциальности)

UserControl1 - содержит три глобальные списки, называемые улицы, дома, автомобили и

Street - содержит два списка только связанные с ним дома и машины, называемые MyHouses и MyCars

Дом - представлен в DataGrid, при этом одним столбцом является DataGridComboboxColumn, чтобы выбрать, с какой улицей этот дом связан. Имеет свойство Street, называемое Street, объявленное в нем, чтобы отслеживать это и выполнять другие вычисления в get/set.

Автомобиль - представлен в DataGrid, при этом одним столбцом является DataGridComboboxColumn, чтобы выбрать, с какой улицей связан этот автомобиль. Имеет свойство 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> 

ответ

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 в DataGrid, со всеми соответствующими столбцами и селективных улиц (вы можете адаптировать для Houses аналогичным образом).

Как я думаю, вы прочитали, DataGridComboBoxColumn немного странно о разрешении DataContext. Когда вы пытаетесь установить ItemsSource в верхней части DataGridComboBoxColumn, это вызывает путаницу.

это должно работать для описанного вами примера (который я смоделировал с Cars и Houses, имеющим объект Street в качестве свойства отслеживания, а не идентификатор).

Если вы решили, что хотите включить SelectedValue и использовать возвращаемый Street ID (для хранения в качестве идентификационных свойств на Car и House, я думаю, что вы должны сделать это с другим сеттер в шаблонах стиле.

Редактировать: Макет, который я использовал (Datacontext установлен для себя в XAML). NB объекты не будут отслеживать друг друга (поскольку я не был уверен, что у вас было).

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>(); 
    } 
} 
+0

В качестве пояснения все свойства, о которых я упоминал в своем первоначальном сообщении, являются фактически полями свойств Dependency Property, если это имеет значение. Ваш вопрос об установке элемента ItemsSource для DataGridComboBoxColumn помогает. Не могли бы вы рассказать об установщике? Это свойство ? Мне не нужен был бы стиль редактирования, верно? – unwrittenrainbow

+0

А я вижу. Что касается «Setter», то в настоящий момент поведение по умолчанию будет состоять в том, чтобы столбец передал выбранный объект «Street» в устройство set 'Street', потому что коллекция, связанная с ComboBox, представляет собой коллекцию« Street »(вы можете отлаживать сеттер и смотреть, что получится). Если вам вместо этого нужно передать 'StreetID' в свойство' StreetID' на вашем 'Car', вам нужно будет использовать установщик' SelectedValue', чтобы получить конкретное свойство. – Chris

+0

Я думаю, что синтаксис, упомянутый выше '' будет правильным, но я думаю, что это поведение по умолчанию в этом случае (я не близок к моему макету Я не могу проверить). – Chris

0

Несмотря на то что глобальные списки ObservableCollections, они, кажется, не стреляя PropertyChangedEvents во конструкторе кода позади. После добавления вещей я установил ItemSource в код, и теперь он работает нормально. Что действительно не имеет никакого смысла, так это то, что события, связанные с изменением свойств, запускаются после того, как улицы появляются в объектах «Дом и автомобиль», потому что оба знают об изменениях друг друга. Используя настройку, которую написал Крис в коде, работая, я отмечаю его пост как ответ. Я понятия не имею, почему списки пустые, только привязанные к этой установке в XAML.

+0

Привет, я могу опубликовать свой макет, если вообще полезно, возможно, я делаю что-то немного другое. – Chris

+0

Это было бы здорово. Это должно быть что-то глупое в этот момент, поэтому прямое сравнение может пролить свет. Спасибо! – unwrittenrainbow

+0

Я отправлю это, когда вернусь домой = D – Chris