Diskuze: Skrollovanie v listboxe
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 8 zpráv z 8.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<ScrollViewer>
<ListBox Name="listBox"/>
</ScrollViewer>
</Grid>
</Window>
Vlož ten ListBox do ScrollViewru
Potom iba označiš item v ListBoxe myšou a scrolluješ až dokonca. Mne to ide, ak to je teda to čo chceš, inak som ta asi nepochopil.
Oh funguje skvelo vďaka, to mi vôbec nenapadlo. Hral som sa len so scrollviewerom v listboxe tedy <ListBox ScrollViewer.xxx >. Ešte raz vďaka.
Ešte raz sa vrátim k tejto téme. Listbox vložený do ScrollViewru funguje ako má avšak všimol som si, že ak dosiahnem koniec zoznamu, tak stlačenie šípky dolu ma niekedy vráti znovu na začiatok. Nie vždy je to vhodné. Je prosím možné toto vypnúť nejakou vlastnosťou toho scrolviewru alebo musím robiť ručne odchytenie dolnej šípky? Pripadá mi to ako ísť s delom na vrabce no neviem nič jednoduchšie nájsť. Mám dojem, že sa to deje hlavne vtedy, ak je v listboxe málo položiek, teda menej ako sa zmestí na jednu obrazovku. Ak je položiek viac a obsah prescrolluje cez viac obrazoviek, tak po dosiahnutí konca ostane focus na konci tak ako má. Chcel by som takéto správanie dosiahnuť u každého počtu položiek.
Ukáž kód, alebo aspoň ten kus kódu, pretože mne osobne to nerobí. Skúšal sem to
Nemyslím si, že odchytávanie šipiek je dobrá cesta. Jj, je to kanón
Ale ak je nato niaka
udalosť tak onej neviem. Skús pozrieť oficiálnu dokumentáciu
Ahoj no kod je v podstate jednoduchy. Xaml vyzera asi takto
<Window Name="OknoPoznamky"
x:Class="Organiser.Poznamky.PoznamkyWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Organiser"
mc:Ignorable="d"
Title="{Binding Titulok}" Height="450" Width="800"
WindowStartupLocation="CenterScreen"
>
<Window.CommandBindings>
<CommandBinding Command="local:Prikazy.VybratVsetko"
CanExecute="VybratVsetkoCommand_CanExecute"
Executed="VybratVsetkoCommand_Executed" />
XXX
</Window.CommandBindings>
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="*" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Menu Name="hlavneMenu" Grid.Row="0" Grid.Column="0" Margin="15" HorizontalAlignment="Center" VerticalAlignment="Center" IsMainMenu="True" FontSize="14" KeyboardNavigation.TabNavigation="None" IsTabStop="True" >
<MenuItem Name="menuZaznam" Header="Záznam" >
<MenuItem Command="local:Prikazy.VybratVsetko" />
XXX
</MenuItem>
</Menu>
<ScrollViewer Grid.Row="1" Margin="15" HorizontalAlignment="Center"
VerticalAlignment="Center" >
<ListBox Name="zoznamListBox" Grid.Row="1" Grid.Column="0" Margin="15"
HorizontalAlignment="Center" VerticalAlignment="Center"
IsSynchronizedWithCurrentItem="True" SelectionMode="Extended"
ItemsSource="{Binding List}" >
<ListBox.InputBindings>
<KeyBinding Command="local:Prikazy.VybratVsetko" Modifiers="Ctrl" Key="A"
/>
XXX
</ListBox.InputBindings>
</ListBox>
</ScrollViewer>
<StatusBar Grid.Row="2" Grid.Column="0" VerticalAlignment="Bottom"
HorizontalAlignment="Left" Margin="15" >
<TextBlock Text="{Binding Stav}" HorizontalAlignment="Center"
VerticalAlignment="Center" />
</StatusBar>
</Grid>
</Window>
V code behind mam osetrenu iba nasledovnu udalost aby sa mi po nacitani
novych dat focusla prva polozka:
void OnGeneratorStatusChanged(object sender, EventArgs e)
{
if (zoznamListBox.ItemContainerGenerator.Status ==
GeneratorStatus.ContainersGenerated)
{
zoznamListBox.SelectedIndex = 0;
zoznamListBox.SelectedItem = 0;
zoznamListBox.ScrollIntoView(zoznamListBox.SelectedItem);
var pl =
(ListBoxItem)zoznamListBox.ItemContainerGenerator.ContainerFromItem(zoznamListBox.SelectedItem);
if (pl != null)
pl.Focus();
}
}
Oknu teda dominuje listbox kde su zobrazene moje zaznamy, nacitane z bindovaneho Listu. Funkcne vsetko pracuje ako ma ale mierne ma irituje, ze ak je listbox focusnuty, co vlastne po celu dobu je, tak klavesove skratky nefunguju tak, ako by bezne mali.
Toto momentalne riesim vlastnym prikazom
public static readonly RoutedUICommand VyberPolozkyOdZaciatku = new RoutedUICommand("VyberPolozkyOdZaciatku", "VyberPolozkyOdZaciatku", typeof(Prikazy), new InputGestureCollection() { new KeyGesture(Key.Home,ModifierKeys.Shift) });
potom v code behind okna
void VyberPolozkyOdZaciatkuCommand_Executed(object sender,
ExecutedRoutedEventArgs e)
{
int vybrataPolozka = zoznamListBox.SelectedIndex;
for (int i=0; i<=vybrataPolozka;i++)
{
zoznamListBox.SelectedItems.Add(zoznamListBox.Items[i]);
}
}
a napokon v xaml
<ListBox.InputBindings>
<KeyBinding Command="local:Prikazy.VybratVsetko" Modifiers="Ctrl" Key="A"
/>
<KeyBinding Key="Home" Modifiers="Shift"
Command="local:Prikazy.VyberPolozkyOdZaciatku" />
</ListBox.InputBindings>
3. Asi co ma najviac irituje, ze klavesove skratky prikazov listbox ignoruje.
Mam vyrobene CustomCommands ako napriklad VybratVsetko. Tento je uvedeny vo
Window.CommandBindings a priradeny polozke menu. pripadne by som ho mohol
priradit polozke kontextoveho menu alebo inde co je ak dobre chapem prave zmysel
Commands - mat jeden prikaz, ktory je volany z viacerych miest. Ak je ale focus
na listboxe tak klavesova skratka nefunguje. Listbox ma svoju vlastnu, vykona to
co ma sam definovane - teda vyberie vsetky polozky - ale nevykona sa to, co mam
ja napisane v implementacii svojho prikazu. Teda evidentne listbox niektore
klavesove skratky ignoruje a musim ich zvlast doplnat do casti
ListBox.InputBindings co je v pohode, ak je program zalozeny na jednom
ListBoxe, no ak by som mal napr. obrazovku s viacerymi Listboxmi je docela
otrava kazdemu objektu zvlast vypisovat skratky, ak mam definovany command. Ten
by proste mal mat prednost, ale nema.
No a toto riesim jedine pridanim comamnds do listbox.inputBindings hoci
jednoduchšie by sa mi zdalo buď proste klavesove skratky listboxu vypnut aby
mali prioritu tie z prikazov, alebo jednoducho osetrovat udalosti keydown, lenze
to nepomoze, lebo listbox najprv vykona svoje definovane ukony a v pripade
kolizie osetrenie z keydown ignoruje..
Zobrazeno 8 zpráv z 8.