xamllistviewcomboboxironpythoninotifycollectionchanged

How to add items to a combobox with IronPython and XAML


I have the following XAML

          <ListView  x:Name="listViewTarget" Height="560" Canvas.Left="10" Canvas.Top="101" Width="924" AllowDrop="True">
            <ListView.View>
                <GridView>
                    <GridViewColumn  Width="350" Header="File or Email">

                    </GridViewColumn>
                    <GridViewColumn   Width="500" Header="Awaiting Item" >
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <ComboBox Width="350" x:Name="cboAI" HorizontalAlignment="Right">
                                </ComboBox>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>

The ListView has two columns, in the second column I need a combobox of options.

I have a drag drop event associated with the ListView, when you drag a file onto the list the filenames are dynamically added successfully to the list view.

 def listView_drag_drop(sender, e):    
     data = e.Data.GetData(DataFormats.FileDrop, False) 
     for s in data:
        sender.Items.Add(s)


lstViewDropTarget = LogicalTreeHelper.FindLogicalNode(_tikitSender,listViewTarget')
lstViewDropTarget.Drop += listView_drag_drop

What I need to do inside that event is to also populate the combobox, which is currently empty.

I have tried to work out how to get a reference to the combobox to be able to set its ItemsSource property, but after days of effort I have failed.

I am new to IronPython and appreciate your help.

EDIT: I tried many ways of getting a reference to the combo without success.

Now I am trying to use the Loaded event, but I get an error :

Failed to create a 'Loaded' from the text 'ComboBox_Loaded'

      <ListView  x:Name="listViewTarget" Height="560" Canvas.Left="10" Canvas.Top="101" Width="924" AllowDrop="True">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel x:Name="test">
                        <Label x:Name="textFileName" Content="ABC" />
                        <TextBlock Text="DEF"/>
                        <ComboBox
                                HorizontalAlignment="Left"
                                Margin="10,10,0,0"
                                VerticalAlignment="Top"
                                Width="120"
                                Loaded="ComboBox_Loaded"/>
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

In Iron Python I define the event:

 def ComboBox_Loaded(sender, e):
    MessageBox.Show("Test")

EDIT 2: Now I am trying to use the ListView CollectionChanged event

lstViewDropTarget.Items.CollectionChanged += ListView_ItemChanged

And here is the event code

def ListView_ItemChanged(sender, e):
   MessageBox.Show(e.NewItems.Count.ToString())

That works messagebox shows '1'

So I can access the new item using e.NewItems[0]

But how do I access the controls?!

I try:

MessageBox.Show(e.NewItems[0].Children.Count.ToString())

and that fails to execute so I try:

MessageBox.Show(e.NewItems[0].Content.Children.Count.ToString())

that also fails

I am very fed up, I cant believe its so very very hard


Solution

  • After trying many ideas and climbing the Iron Python learning curve I have a working solution. Whilst I have switched to a DataGrid, the method I have used would work with a ListView.

    The first breakthrough came when I tried to bind the combobox to array within an iron python class. It just thought I would try and behold it worked!

    There were further problems with SelectedItem and needing both a CellTemplate and a CellEditingTemplate, otherwise the selected item doesn't show when the combo loses focus.

    I am quite pleased with the result, now I can just iterate through the DataGrid Items to save the results.

     <DataGrid x:Name="gridUnknownDocuments" FontFamily="Segoe UI" FontWeight="Normal" FontSize="14" Height="294" Width="904" AutoGenerateColumns="False" SelectionUnit="Cell" Canvas.Left="20" Canvas.Top="39" >
    <DataGrid.Columns>
        <DataGridTextColumn Header="StepID" Binding="{Binding StepID}" IsReadOnly="True" />
        <DataGridTextColumn Header="Document name" Binding="{Binding DocName}" IsReadOnly="True" />
        <DataGridTemplateColumn  Header="Awaiting Item">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Margin="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="{Binding SelectedAwaitingItem, Mode=TwoWay}" Width="Auto" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <ComboBox Height="23" 
                        ItemsSource="{Binding Path= Items}"
                        SelectedValue="{Binding Path=SelectedAwaitingItem, Mode=TwoWay}" Width="Auto">
                    </ComboBox>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
    
    </DataGrid.Columns>
    

    IronPython Class:

    class UnknownDocuments(object):
    def __init__(self, StepID, DocName,Items,FromTypes):
      self.StepID = StepID
      self.DocName = DocName
      self.SelectedAwaitingItem = ""
      self.Items = Items
      self.FromTypes=FromTypes
      self.SelectedFromType = ""
    

    Populating the DataGrid (from SQL Server):

    def PopUnknownDocuments():
    # Populate unknown docs grid
      strSql="EXEC upLean_GetUnknownDocuments  @EntityRef='"+_tikitEntity+"', @MatterNo="+_tikitMatter.ToString()
      gridUnknownDocs = LogicalTreeHelper.FindLogicalNode(_tikitSender, 'gridUnknownDocuments')
    
      _tikitDbAccess.Open(strSql)
      if _tikitDbAccess._dr is not None:
      dr = _tikitDbAccess._dr
      if dr.HasRows:
        item = []
        while dr.Read():
          if not dr.IsDBNull(0):
            item.append(UnknownDocuments(dr.GetString(0), dr.GetString(1),["NA","Awaiting A","Awaiting B"],["Internal","Client","Other Side"]))
      gridUnknownDocs.ItemsSource = item
    dr.Close()
    

    enter image description here