Список wpf с DataTemplate не выбирает элемент при выборе элемента управления шаблоном

У меня есть список с шаблоном данных. Шаблон данных очень простой, он содержит два текстовых поля. Если я щелкну за пределами текстовых полей в сетке вокруг них, поле со списком выберет строку. Если я щелкаю текстовое поле, текстовое поле принимает фокус, но поле со списком не выделяет эту строку. Я нарисовал шаблон с помощью Expression Blend, если это помогает объяснить некоторые значения, маржу и т. Д.

Вот шаблон данных:

<DataTemplate DataType="{x:Type Scratch:CollectionItem}">
        <Grid Height="20" Width="288">
            <TextBox HorizontalAlignment="Left" Margin="8,0,0,0" TextWrapping="Wrap" Text="{Binding Id}" VerticalAlignment="Top" Width="86"/>
            <TextBox Margin="98,0,0,0" TextWrapping="Wrap" Text="{Binding Detail}" VerticalAlignment="Top"/>
        </Grid>
    </DataTemplate>

person Ian    schedule 22.12.2010    source источник


Ответы (2)


См. Выбор элемента текстового поля в списке не изменяет выбранный элемент списка

person devdigital    schedule 22.12.2010
comment
Мне здесь явно чего-то не хватает. Я добавил PreviewMouseDown = PreviewMouseDown GotFocus = GotFocus в каждое из текстовых полей, но события никогда не возникают. GotFocus и PreviewMouseDown существуют как методы в Window. Любые идеи? - person Ian; 22.12.2010
comment
Не обращая внимания, я закрыл Visual Studio и снова открыл ее, и все начало работать: / - person Ian; 22.12.2010

Я подумал, что добавлю свой собственный ответ, чтобы расширить то, что я узнал. Я сделал что-то, чего не было в приведенном выше ответе.

Итак, у меня есть DataTemplate:

<DataTemplate DataType="{x:Type Scratch:CollectionItem}">
    <Grid Height="20" Width="288">
    <TextBox HorizontalAlignment="Left" Margin="8,0,0,0" TextWrapping="Wrap" Text="{Binding Id}" VerticalAlignment="Top" Width="86" PreviewMouseDown="APreviewMouseDown" GotFocus="AGotFocus" GotKeyboardFocus="AGotKeyboardFocus" PreviewGotKeyboardFocus="AGotKeyboardFocus"/>
    <TextBox Margin="98,0,0,0" TextWrapping="Wrap" Text="{Binding Detail}" VerticalAlignment="Top" PreviewMouseDown="APreviewMouseDown" GotFocus="AGotFocus" GotKeyboardFocus="AGotKeyboardFocus" PreviewGotKeyboardFocus="AGotKeyboardFocus"/>
</Grid>

All the events fire, I eventually settled on GotFocus. The A* names were from where I was trying to rename things to see why events were not firing. Quitting Visual Studio and restarting seemed to fix it. This machine is not very reliable.

Как видите, DataTemplate предназначен для элементов типа CollectionItem. Я экспериментировал с коллекциями INotifyPropertyChanged и Observable. Детали не важны.

My ListBox привязан к {Binding Path = Items}, где Items - это ObservableCollection

Мое событие получения фокуса - это вариант решений, найденных в другом потоке. Поскольку мой ListBox напрямую привязан к списку объектов CollectionItem, следующее работает и кажется более чистым, чем обработка шаблонного родителя и т. Д.

private void AGotFocus(object sender, RoutedEventArgs e)
{
    try
    {
        FrameworkElement element = sender as FrameworkElement;
        CollectionItem item = element.DataContext as CollectionItem;
        if (item != null)
        {
            listBox2.SelectedValue = item;
        }
    }
    catch { }
}

Итак, в приведенном выше случае отправитель является одним из двух текстовых полей, его DataContext указывает на CollectionItem, и мы можем установить элемент списка, который будет выбран, выбрав этот элемент.

Не знаю, поможет ли это кому-нибудь, но это уже есть :)

person Ian    schedule 22.12.2010