Bonjour à tous,

Je connais actuellement quelques déboires en essayant de faire un binding sur un datagrid avec une colonne qui contient une combobox. J'ai d'abord essayé avec un DataGridComboboxColumn mais j'ai vu sur internet que c'était plus facile à gérer en créant un template sur la colonne comme ceci :

Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<DataGrid Name="PortsDataGrid"
  Grid.Row="6"
  Grid.ColumnSpan="4"
  CanUserAddRows="True"
  ItemsSource="{Binding Ports, Mode=TwoWay}"
  AutoGenerateColumns="False">
	<DataGridTextColumn Header="Port" Binding="{Binding Port}"/>
	<DataGridTemplateColumn Header="Port type">
		<DataGridTemplateColumn.CellTemplate>
			<DataTemplate>
				<ComboBox ItemsSource="{StaticResource PortTypes}" SelectedItem="{Binding PortType}" />
			</DataTemplate>
		</DataGridTemplateColumn.CellTemplate>
	</DataGridTemplateColumn>
</DataGrid>

Ce que je cherche à binder sur la combobox c'est un type Enum que voici :

Code vb.net : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
 
Public Enum PortType
    Optical
    Electrical
End Enum

Le problème actuel est que j'ai une exception du type :

Une exception non gérée du type 'System.InvalidOperationException' s'est produite dans PresentationFramework.dll
Informations supplémentaires*: La collection Items doit être vide pour pouvoir utiliser ItemsSource.
Ce que je ne comprends pas puisque ma collection du DataGrid est forcément vide. Et chose encore plus étrange je n'ai pas cette exception lorsque j'utilise un DataGridComboboxColumn (à la place tu template de cellule), mais dans ce cas la fenêtre est instable et plante au moindre changement donnée avec cette exception :

InvalidOperationException
'DeferRefresh' n'est pas autorisé durant une transaction AddNew ou EditItem.
Alors si qqn peut m'aider à faire fonctionner correctement mon datagrid avec l'une ou l'autre solution (DataGridComboboxColumn ou template sur la cellule avec Combobox).

Je remets le code complet xaml et vb de la fenêtre :
Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<Grid>
  <Grid.RowDefinitions>
    <RowDefinition Height="*"/>
    <RowDefinition Height="*"/>
    <RowDefinition Height="*"/>
    <RowDefinition Height="*"/>
    <RowDefinition Height="3*"/>
    <RowDefinition Height="*"/>
    <RowDefinition Height="3*"/>
    <RowDefinition Height="*"/>
  </Grid.RowDefinitions>
 
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="2*"/>
    <ColumnDefinition Width="4*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
  </Grid.ColumnDefinitions>
 
  <Label Content="Name" Grid.Row="0" Grid.Column="0" Name="NameLabel" VerticalAlignment="Center" />
  <Label Content="Type" Grid.Row="1" Grid.Column="0" Name="TypeLabel" VerticalAlignment="Center" />
  <Label Content="Sub-type" Grid.Row="2" Grid.Column="0" Name="SubTypeLabel" VerticalAlignment="Center" />
  <TextBox Name="NameTextBox" Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" Text="{Binding Name, Mode=TwoWay}"/>
  <ComboBox Name="TypeComboBox" Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" ItemsSource="{StaticResource NDTypes}" SelectedValue="{Binding Type, Mode=TwoWay}"/>
  <ComboBox Name="SubTypeComboBox" Grid.Row="2" Grid.Column="1" VerticalAlignment="Center" ItemsSource="{StaticResource NESubTypes}" SelectedValue="{Binding SubType, Mode=TwoWay}"/>
 
  <Label Content="Loopback addresses" Grid.Row="3" Grid.Column="0" Name="LoopbackLabel" VerticalAlignment="Center" />
  <DataGrid Name="HostsDataGrid"
    Grid.Row="4"
    Grid.ColumnSpan="4"
    CanUserAddRows="True"
    ItemsSource="{Binding LoopbackAddresses, Mode=TwoWay}"
    AutoGenerateColumns="False">
    <DataGrid.Columns>
      <DataGridTextColumn Header="IP Address" Binding="{Binding IPAddress, Converter={StaticResource IPATSConverter}}"/>
      <DataGridTextColumn Header="IP Mask" Binding="{Binding IPMask, Converter={StaticResource IPATSConverter}}"/>
    </DataGrid.Columns>
  </DataGrid>
 
  <Label Content="Ports" Grid.Row="5" Grid.Column="0" Name="PortsLabel" VerticalAlignment="Center" />
  <!--<DataGrid Name="PortsDataGrid"
    Grid.Row="6"
    Grid.ColumnSpan="4"
    CanUserAddRows="True"
    ItemsSource="{Binding Ports, Mode=TwoWay}"
    AutoGenerateColumns="False">
    <DataGrid.Columns>
      <DataGridTextColumn Header="Port" Binding="{Binding Port}"/>
      <DataGridComboBoxColumn Header="Port type" ItemsSource="{StaticResource PortTypes}" SelectedItemBinding="{Binding PortType}"/>
    </DataGrid.Columns>
  </DataGrid>-->
  <DataGrid Name="PortsDataGrid"
    Grid.Row="6"
    Grid.ColumnSpan="4"
    CanUserAddRows="True"
    ItemsSource="{Binding Ports, Mode=TwoWay}"
    AutoGenerateColumns="False">
    <DataGridTextColumn Header="Port" Binding="{Binding Port}"/>
    <DataGridTemplateColumn Header="Port type">
      <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
          <ComboBox ItemsSource="{StaticResource PortTypes}" SelectedItem="{Binding PortType}" />
        </DataTemplate>
      </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
  </DataGrid>
 
  <ComboBox Name="NEChoiceComboBox" Grid.Row="7" Grid.Column="0" VerticalAlignment="Center"/>
  <Button Name="CancelButton" Width="80" IsCancel="True" Content="Cancel" Grid.Row="7" Grid.Column="2" VerticalAlignment="Center"/>
  <Button Name="OkButton" Width="80" IsDefault="True" Content="OK" Grid.Row="7" Grid.Column="3" VerticalAlignment="Center"/>
</Grid>
Code vb.net : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
Public Class NEOptionsWindow
 
    Private _mainWindow As MainWindow
 
    Public Sub New(ByVal aMainWindow As MainWindow)
        _mainWindow = aMainWindow
        Me.Resources.Add("NDTypes", _mainWindow.NDTypes)
        Me.Resources.Add("NESubTypes", _mainWindow.NESubTypes)
 
        Dim portTypes As Array = [Enum].GetNames(GetType(PortType))
        Me.Resources.Add("PortTypes", portTypes)
 
        InitializeComponent()
        Me.Show()
    End Sub
 
End Class

Et la classe Port bien sûr :
Code vb.net : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
Public Class Port
    Private _port As String
    Private _portType As PortType
 
Public Property Port As String
    Get
        Return _port
    End Get
    Set(ByVal newPort As String)
        _port = newPort
    End Set
    End Property
 
    Public Property PortType As PortType
        Get
            Return _portType
        End Get
        Set(ByVal newPortType As PortType)
            _portType = newPortType
        End Set
    End Property
 
    Sub New(ByVal aPort As String, ByVal aPortType As PortType)
        _port = aPort
        _portType = aPortType
    End Sub
End Class