Как получить уровень ячеек ComboBox для WPF DataGrid? - PullRequest
6 голосов
/ 02 октября 2010

Похоже, что WFP DataGridComboBoxColumn использует один элемент ItemsSource для всех ячеек в этом столбце.У меня есть случай, когда элементы ComboBox зависят от другой ячейки в той же строке.Мне удалось заполнить ItemsSource в событии PreparingCellForEdit.Тем не менее, это не работает, как хотелось бы.Изначально все ячейки в этом столбце пустые.Как только я заполняю ItemsSource для ComboBox этого столбца, все связанные ячейки (с тем же источником элементов) показывают значения.Однако, если я щелкну ячейку другого типа (заполняется другой источник элементов), все значения исчезнут, а ячейки нового типа отобразят значения.Вы можете использовать только один набор элементов источника для столбца?Я не могу поверить, что это правда.Я что-то пропустил?Любое решение?

Ответы [ 2 ]

2 голосов
/ 02 октября 2010

Вы, вероятно, не можете сделать это надежно. Сетка может повторно использовать поле со списком или случайным образом создавать / уничтожать его.

Случайно я просто работаю на экране, который делает именно это. Учитывая эти ...

  • Каждая строка в сетке привязана к объекту типа Trade.
  • Каждая сделка имеет государственную собственность
  • Каждая сделка имеет свойство TerritoryCanidates
  • Изменение свойства State приведет к изменению свойства TerritoryCanidates

Это дает мне возможность привязывать ItemsSource к свойству TerritoryCanidates. Что, в свою очередь, DataGrid будет соблюдать при любых обстоятельствах.


<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
    <DataGrid Name="Zoom" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="State">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding State}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox SelectedItem="{Binding State}" ItemsSource="{Binding StateCanidates}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>

            <DataGridTemplateColumn Header="Territory">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Territory}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox SelectedItem="{Binding Territory}" ItemsSource="{Binding TerritoryCanidates}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>

        </DataGrid.Columns>

    </DataGrid>
</Grid>
</Window>


Imports System.ComponentModel

Class MainWindow
Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
    Dim x As New List(Of Model)
    x.Add(New Model)
    x.Add(New Model)
    x.Add(New Model)

    Zoom.ItemsSource = x
End Sub
End Class

Class Model
Implements INotifyPropertyChanged

Public ReadOnly Property StateCanidates As List(Of String)
    Get
        Return New List(Of String) From {"CA", "TX", "NY"}
    End Get
End Property

Public ReadOnly Property TerritoryCanidates As List(Of String)
    Get
        If State = "" Then Return Nothing
        Return New List(Of String) From {State & "1", State & "2"}
    End Get
End Property

Private m_State As String
Public Property State() As String
    Get
        Return m_State
    End Get
    Set(ByVal value As String)
        m_State = value
        OnPropertyChanged("State")
        OnPropertyChanged("TerritoryCanidates")
    End Set
End Property

Private m_Territory As String
Public Property Territory() As String
    Get
        Return m_Territory
    End Get
    Set(ByVal value As String)
        m_Territory = value
        OnPropertyChanged("Territory")
    End Set
End Property




Public Sub OnPropertyChanged(ByVal propertyName As String)
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub

Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
End Class
1 голос
/ 03 октября 2010

Благодаря примеру Джонатана я решил свою проблему следующим образом.Я изменил код Джонатана, чтобы подчеркнуть свое решение.Я удалил свойство Territory из его примера, потому что оно мне не нужно для моей проблемы.

Есть два столбца.Первый столбец - Государство.Второй столбец - StateCandidate.Столбец State связан со списком состояний, а столбец StateCandidate связан со списком StateCandidates.Ключевым моментом является то, что список StateCandidates воссоздается при изменении состояния.Таким образом, в каждой строке может быть разный список StateCandidates (в зависимости от выбранного состояния).

Обратите внимание, что при изменении состояния он не будет обновлять список StateCandidates до тех пор, пока не будет выбрана другая строка, что является отдельной проблемой, с которой я буду бороться.Кто-нибудь знает, как я могу заставить совершить?

Еще раз спасибо Джонатану за его вдохновение.Я буду продолжать искать лучшее решение.

...