none
Aggiornare ComboBox all'interno di una itemtemplate RRS feed

  • Domanda

  •        Ho una combobox dentro una list view:

                            <ListView DockPanel.Dock="Top" ItemsSource="{Binding Source={StaticResource S3DocumentiProveViewSource}}" Name="S3DocumentiProveListView" SelectionMode="Single" Width="400">
                                <ListView.ItemTemplate>
                                    <DataTemplate>
                                        <Expander Header="{Binding Path=NomeFile, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" Margin="5" Background="#FFC4DBDE" Width="370">
                                            <Grid x:Name="LayoutRoot" Height="150">
                                            <Grid.RowDefinitions>
                                                <RowDefinition Height="Auto"/>
                                                <RowDefinition Height="Auto"/>
                                                <RowDefinition Height="Auto"/>
                                                <RowDefinition Height="Auto"/>
                                            </Grid.RowDefinitions>
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="80"/>
                                                <ColumnDefinition/>
                                            </Grid.ColumnDefinitions>
                                            <Label Margin="2" Content="Categoria:" />
                                            <ComboBox Margin="2" Grid.Column="1" SelectedValue="{Binding Path=Categoria}" Name="CategoriaComboBoxColumn" ItemsSource="{Binding Source={StaticResource myStrings}}" />
                                            <Label Margin="2" Grid.Row="1" Content="Titolo:" />
                                            <TextBox Margin="2" Grid.Row="1" Grid.Column="1" Text="{Binding Path=Titolo, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" />
                                            <!--<Label Margin="2" Grid.Row="2" Content="Nome File:" />
                                            <TextBlock Margin="2" Grid.Row="2" Grid.Column="1" Text="{Binding Path=NomeFile}" />-->
                                            <Label Margin="2" Grid.Row="3" Content="Note:" />
                                            <TextBox Margin="2" Grid.Row="3" Grid.Column="1" Text="{Binding Path=Note, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" Height="40" TextWrapping="Wrap" />
                                        </Grid>
                                        </Expander>
                                    </DataTemplate>
                                </ListView.ItemTemplate>
                            </ListView>
    

    tale combobox è popolata da una lista di stringhe contenuta nella resource:

            <x:Array x:Key="myStrings" Type="sys:String">
                <sys:String>one</sys:String>
                <sys:String>two</sys:String>
            </x:Array>
    

    tutto funziona correttamente ma vorrei aggiornare gli item della combobox a runtime.

    ho provato ad aggiornare l'array in questo modo:

            Dim Arr As Array
            Arr = CType(Me.FindResource("myStrings"), Array)
            For Each r In DScategoria.Tables(0).Rows
                S3DocumentiProveCategoriaList.Add(r.item("Valore"))
            Next
            Arr = S3DocumentiProveCategoriaList.ToArray

    ed in effetti l'array viene aggiornato correttamente ma non si ripercuote sulla combobox che mantiene la lista originaria.

    dove sbaglio oppure c'è altra strada?

    grazie

    Marco

    venerdì 15 novembre 2013 10:13

Risposte

  • Ciao,

    il problema è che stai usando un array di string qui :

    <x:Array x:Key="myStrings" Type="sys:String">
                <sys:String>one</sys:String>
                <sys:String>two</sys:String>
            </x:Array>


    il che non va d'accordo con la notifica di cambio di proprietà quando aggiungi o rimuovi elementi, quindi ti proporrei di creare una classe che eredita da System.Collections.ObjectModel.ObservableCollection(Of Object) (object perché lo puoi usare anche per altro così) in questo modo :

    Public Class ObservableArray
    	Inherits ObservableCollection(Of Object)
    End Class

    a questo punto puoi utilizzarla nello xaml in questo modo :

    <.... ... xmlns:local="clr-namespace:mioNamespace" xmlns:sys="clr-namespace:System;assembly=mscorlib" ... ... >

    ....

    ...

    <local:ObservableArray x:Key="myStrings">
                <sys:String>One</sys:String>
                <sys:String>Two</sys:String>
            </local:ObservableArray>


    Questo dovrebbe risolvere il tuo problema.

    • Contrassegnato come risposta itamarcus venerdì 15 novembre 2013 16:30
    venerdì 15 novembre 2013 13:54
    Postatore

Tutte le risposte

  • Ciao Marco,

    potresti provare in questo modo: lato XAML

    <ComboBox Margin="2" SelectedValue="{Binding Path=Categoria}" Name="CategoriaComboBoxColumn" ItemsSource="{Binding}" />

    nell'evento Loaded della tua Window

    Dim opzioni As New List(Of String)
    opzioni.Add("one")
    opzioni.Add("two")
    
    CategoriaComboBoxColumn.ItemsSource = opzioni

    In sostanza, mi sono creato una lista di stringhe, in cui ho inserito i valori che erano presenti nella tua static resource. Poi, ho collegato alla proprietà ItemSource della Combo (che esegue il binding dei dati), la lista così creata.

    Spero di esserti stato di aiuto.


    Emiliano Musso

    venerdì 15 novembre 2013 10:26
  • non riesco perchè non'è accessibile...ci avevo già provato all'inizio..

    'CategoriaComboBoxColumn' non dichiarato. Non è accessibile a causa del livello di protezione.

    venerdì 15 novembre 2013 10:31
  • Se si trattasse di tradurre la tua ListView in un DataGrid, sarebbe possibile oppure ti comporta problemi di qualche altro tipo?

    Emiliano Musso

    venerdì 15 novembre 2013 10:38
  • la datagrid l'ho provata inizialmente ma dopo averla stilizzata un pò per esigenze grafiche mi restituiva errori di aggiornamento sul database.

    in pratica un campo note spostato come textbox nell'area rowdetails per esigenze di spazio non ne voleva sapere di aggiornarsi ed ogni tanto mi restituiva errore di concorrenza...

    ovviamente con un datagrid classico tutto funziona egregiamente ma l'interfaccia è pessima.

    grazie

    venerdì 15 novembre 2013 11:00
  • Ciao,

    il problema è che stai usando un array di string qui :

    <x:Array x:Key="myStrings" Type="sys:String">
                <sys:String>one</sys:String>
                <sys:String>two</sys:String>
            </x:Array>


    il che non va d'accordo con la notifica di cambio di proprietà quando aggiungi o rimuovi elementi, quindi ti proporrei di creare una classe che eredita da System.Collections.ObjectModel.ObservableCollection(Of Object) (object perché lo puoi usare anche per altro così) in questo modo :

    Public Class ObservableArray
    	Inherits ObservableCollection(Of Object)
    End Class

    a questo punto puoi utilizzarla nello xaml in questo modo :

    <.... ... xmlns:local="clr-namespace:mioNamespace" xmlns:sys="clr-namespace:System;assembly=mscorlib" ... ... >

    ....

    ...

    <local:ObservableArray x:Key="myStrings">
                <sys:String>One</sys:String>
                <sys:String>Two</sys:String>
            </local:ObservableArray>


    Questo dovrebbe risolvere il tuo problema.

    • Contrassegnato come risposta itamarcus venerdì 15 novembre 2013 16:30
    venerdì 15 novembre 2013 13:54
    Postatore
  • perfetto...lavora egregiamente...

    grazie

    venerdì 15 novembre 2013 16:30