У меня есть ListBox, привязанный к коллекции элементов типа Definition. Мое требование состоит в том, чтобы каждый раз, когда мышь наводится на область шаблонного ListBoxItem, рядом с ListBoxItem открывался второй ListBox, открывая подпункты типа Word.

(Я в основном реализую что-то похожее на TreeView, используя два ListBoxes. Это для более ранних версий, поэтому использование элемента управления TreeView не вариант.)

Это структура данных ...

public class Word
{
    public string Name { get; set; }                
}

public class Definition 
{
    public string Name { get; set }
    public ObservableCollection<Word> Words;
}

public class Dictionary
{
    public string Name { get; set }
    public ObservableCollection<Definition> Definitions;
}

А вот представление XAML ...

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>  
    <Button Grid.Row="0"
        Height="0">
        <Button.Flyout>
            <Flyout x:Name="DefinitionFlyout"/>
                <ListBox x:Name="WordsListBox"                                                                                                                                                                                                                       HorizontalAlignment="Stretch">
                    <ListBox.ItemTemplate>
                        <DataTemp late x:DataType="local:Word">
                            <TextBox TextWrapping="NoWrap"                                                                                                                                                                                                                                                         
                                Height="Auto" 
                                BorderThickness="0"
                                HorizontalAlignment="Stretch"
                                Text="{x:Bind Name}"
                                TextAlignment="Left"/>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>              
            </Flyout>
        </Button.Flyout>
    </Button>
    <ListBox x:Name="DefinitionsListBox" 
        Grid.Row="1"                                                     
                SelectionMode="Single"                                                      
                HorizontalAlignment="Stretch">
                <ListBox.ItemContainerStyle>
                    <Style TargetType="ListBoxItem">
                            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                                    <Setter Property="VerticalContentAlignment" Value="Stretch"/>                                                        
                                </Style>
                </ListBox.ItemContainerStyle>
                <ListBox.ItemTemplate>
                    <DataTemplate x:DataType="local:Definition">                                                        
                            <TextBox TextWrapping="NoWrap"                                                                     
                                    Height="Auto"                                                                  
                                        BorderThickness="0"                                                                      
                                        HorizontalAlignment="Stretch"                                                                 
                                        Text="{x:Bind Name, Mode=TwoWay}">                                                                
                                </TextBox>                                                        
                        </DataTemplate>
                </ListBox.ItemTemplate>
        </ListBox>
</Grid>

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

К сожалению, я не могу найти мероприятия, которые помогут мне в этом.

Я думал, что определение PointerEntered и PointerExited в TextBox of Definition поможет, но они этого не делают, потому что PointerExited срабатывает НЕМЕДЛЕННО после PointerEntered, как почти одновременно, а не тогда, когда мышь покидает область TextBox. И SelectionChanged из ListBox не срабатывает.

Первое событие должно срабатывать, когда начинается выделение ListBoxItem, а второе - когда выделение заканчивается.

Что посоветуете для этого, пожалуйста?

0
M Psyllakis 12 Мар 2019 в 20:47

1 ответ

Лучший ответ

Я думал, что определение PointerEntered и PointerExited в TextBox of Definition поможет, но они этого не делают, потому что PointerExited срабатывает НЕМЕДЛЕННО после PointerEntered, как почти одновременно.

Проблема заключается в том, что когда на кнопке отображается Flyout, на окне появляется маскирующий слой. Это предотвратит базовое событие ввода, определенное TextBox. Похоже, что PointerExited срабатывает сразу после PointerEntered почти одновременно.

Для решения этой проблемы вы можете установить свойство OverlayInputPassThroughElement для Flyout, чтобы область ListBox могла реагировать на событие PointerEntered PointerExited при открытии Flyout. Для получения дополнительной информации обратитесь к следующему коду.

 <Flyout x:Name="DefinitionFlyout" OverlayInputPassThroughElement="{x:Bind DefinitionsListBox}">
1
Nico Zhu - MSFT 13 Мар 2019 в 06:54