Domanda

Ho grattato la testa su questo per un po 'di tempo e al momento sono sconcertato.

Lo scenario problematico è più facile da spiegare come codice, quindi spero che parli da solo. Prima di tutto, ho un'applicazione Silverlight con il seguente in XAML ...

<UserControl x:Class="SilverlightApplication2.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Width="400" Height="300">

<UserControl.Resources>
    <DataTemplate x:Key="icTemplate">
        <ComboBox ItemsSource="{Binding StringsChild}" SelectedItem="{Binding SelectedItem}"/>
    </DataTemplate>
</UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <ItemsControl x:Name="ic" ItemTemplate="{StaticResource icTemplate}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Vertical"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>

    <Button Click="Save" Grid.Row="1" Content="GO"/>
</Grid>

Il mio code-behind si presenta così ... (tutto scritto in un unico file di classe in modo che sia facile per te copiarlo nel tuo progetto e compilarlo)

namespace SilverlightApplication2
{
    public partial class Page : UserControl
    {
        public ObservableCollection<SomeClass> StringsParent { get; set; } 

        public Page()
        {   
            InitializeComponent();
            StringsParent = new ObservableCollection<SomeClass>();
            ic.ItemsSource = StringsParent;
        }

        private void Save(object sender, RoutedEventArgs e)
        {
            SomeClass c = new SomeClass();
            c.StringsChild.Add("First");
            c.StringsChild.Add("Second");
            c.StringsChild.SetSelectedItem("Second");
            StringsParent.Add(c);
        }
    }

    public class SomeClass
    {
        public SelectableObservablecollection<string> StringsChild { get; set; }

        public SomeClass()
        {
            StringsChild = new SelectableObservablecollection<string>();
        }    
    }

    public class SelectableObservablecollection<T> : ObservableCollection<T>
    {
        public SelectableObservablecollection()
            : base()
        {

        }

        public void SetSelectedItem<Q>(Q selectedItem)
        {
            foreach (T item in this)
            {
                if (item.Equals(selectedItem))
                {
                    SelectedItem = item;
                    return;
                }
            }
        }

        private T _selectedItem;
        public T SelectedItem
        {
            get
            {
                return _selectedItem;
            }
            set
            {
                _selectedItem = value;
                OnPropertyChanged(new PropertyChangedEventArgs("SelectedItem"));
            }
        }
    }
}

Quindi lasciami spiegare ... Ho deciso di scrivere un modo generico per creare un oggetto ObservableCollection che abbia una proprietà SelectedItem in modo che quando associo la raccolta a un ComboBox, ad esempio, posso associare SelectedItem proprietà ad esso.

Tuttavia, per qualche motivo, non sembra funzionare quando ComboBox viene effettivamente nidificato tramite un ItemTemplate. Ho effettivamente un elenco di elenchi, uno scenario abbastanza semplice che mi sono perso su ciò che è sbagliato.

Quando esegui il codice, vedrai che il ComboBox modello prende gli elementi corretti, ma non è mai impostato su SelectedItem nonostante l'associazione.

So che è piuttosto lungo, ma ... qualche idea?

Grazie mille

È stato utile?

Soluzione

L'output del debugger ti dà in realtà un suggerimento sul problema:

Errore System.Windows.Data: errore percorso BindingExpression: proprietà 'SelectedItem' non trovata in 'ExpressionElements.SomeClass' 'ExpressionElements.SomeClass' (HashCode = 49044892). BindingExpression: Path = 'SelectedItem' DataItem = 'ExpressionElements.SomeClass' (HashCode = 49044892); l'elemento target è 'System.Windows.Controls.ComboBox' (Name = ''); la proprietà target è 'SelectedItem' (digitare 'System.Object') ..

Poiché il contesto Dati per il modello è un'istanza della classe SomeClass, tutto ciò che devi fare è cambiare l'associazione SelectedItem da SelectedItem a StringsChild.SelectedItem :

<DataTemplate x:Key="icTemplate">
    <ComboBox ItemsSource="{Binding StringsChild}" 
     SelectedItem="{Binding StringsChild.SelectedItem}"/>
</DataTemplate>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top