Pergunta

Eu fui coçar a cabeça em um presente por um tempo agora e estou perplexo no momento.

O cenário de problema é mais fácil de explicar como código por isso espero que fala por si. Primeiro de tudo, eu tenho um aplicativo do Silverlight com o seguinte no 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>

Meu código-behind olhares como este ... (todos escritos em um único arquivo de classe de modo que é fácil para você copiá-lo em seu próprio projeto e compilação)

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"));
            }
        }
    }
}

Então, deixe-me explicar ... Me propus a escrever uma forma genérica de se criar uma ObservableCollection que tem um SelectedItem propriedade sobre ela de modo que quando eu ligar a coleção para uma caixa de combinação, por exemplo, eu pode vincular do ComboBox SelectedItem propriedade a ele.

No entanto, por alguma razão, ele não parece trabalho quando a caixa de combinação é efetivamente aninhado através de um ItemTemplate. Eu efetivamente tem uma lista de listas, um cenário que é suficiente simples que eu estou perdido quanto ao que há de errado.

Quando você executa o código, você verá que a caixa de combinação templated faz pegar os itens corretos, mas nunca definido para um SelectedItem apesar da ligação.

Eu sei que é um pouco prolixo, mas ... alguma idéia?

Muito obrigado

Foi útil?

Solução

A saída depurador realmente dá-lhe uma dica para o problema:

System.Windows.Data Erro: BindingExpression caminho de erro: 'SelectedItem' propriedade não foi encontrado na 'ExpressionElements.SomeClass' 'ExpressionElements.SomeClass' (HashCode = 49044892). BindingExpression: Path = 'SelectedItem' DataItem = 'ExpressionElements.SomeClass' (HashCode = 49044892); elemento alvo é 'System.Windows.Controls.ComboBox' (Nome = ''); propriedade de destino é 'SelectedItem' (tipo 'System.Object') ..

Como o contexto de dados para o modelo é uma instância da classe SomeClass, tudo que você tem a fazer é mudar a ligação de SelectedItem para SelectedItem StringsChild.SelectedItem :

<DataTemplate x:Key="icTemplate">
    <ComboBox ItemsSource="{Binding StringsChild}" 
     SelectedItem="{Binding StringsChild.SelectedItem}"/>
</DataTemplate>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top