Я прикрутил к StackPanel скролл, но он не так пока работает как мне хотелось бы.
Он стоит на месте, когда содержимого больше чем высота StackPanel.
Мне же хочется всегда видеть последний добавленный элемент в StackPanel.
Как я понял, мне нужно опускать скролл программно при добавлении элемента в StackPanel, как отловить это событие ? на MSDN про StackPanel что то не нашёл.
Короче говоря: Как называется событие у StackPanel, когда я добавляю в него элемент ?
Универсальный совет, изучающим WPF - почитайте и разберитесь как использовать паттерн MVVM (необязательно по этой ссылке). Большая вероятность, что после освоения MVVM у вас разрешиться множество вопросов, касаемо WPF.
Что касается вашего вопроса: скорее всего, вы идете неверным путем, но, так как вводных данных мало, будем работать с тем, что есть.
StackPanel не имеет события изменения коллекции детей, поэтому мы не можем отследить когда был добавлен или удален элемент. Опять-таки, скорее всего, вам нужно использовать другой контрол, но в качестве альтернативы можно приспособить для этих целей событие LayoutUpdated. Это событие происходит, когда обновляется layout элемента.
Подписываемся на событие и пишем в обработчике логику прокрутки ScrollViewer к последнему элементу:
Xaml:
<ScrollViewer x:Name="sv" Grid.Row="1">
<StackPanel x:Name="stackPanel" />
</ScrollViewer>
<Button Click="AddToStackPanel">Add item to StackPanel</Button>
Code-behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
stackPanel.LayoutUpdated += OnLayoutUpdated;
}
private bool _needToScroll = true;
private void OnLayoutUpdated(object sender, EventArgs e)
{
if (_needToScroll)
{
sv.ScrollToEnd();
_needToScroll = false;
}
}
private void AddToStackPanel(object sender, RoutedEventArgs e)
{
var tb = new TextBlock {Text = DateTime.Now.ToString("hh:mm:ss.fff tt")};
stackPanel.Children.Add(tb);
_needToScroll = true;
}
}
Поле _needToScroll отвечает за то, нужно ли прокручивать ScrollViewer к последнему элементу. Это нужно чтобы пользователь мог вручную использовать прокрутку (не забываем, что при прокрутке layout контрола также обновляется и если флаг не использовать, то контрол будет прокручен всегда к последнему элементу). Соответственно этот флаг нужно устанавливать при добавлении/удалении элементов.
Интуитивно кажется, что вам больше подошел бы ListBox или ItemsControl на которые уже можно навешать поведение прокрутки к последнему элементу. Или же унаследоваться от стандартных и сделать контрол со своим поведением.
Xaml:
<ListBox Grid.Row="1" ItemsSource="{Binding Items}" >
<i:Interaction.Behaviors>
<local:ScrollToLastItemBehavior/>
</i:Interaction.Behaviors>
</ListBox>
<Button Grid.Row="2" Command="{Binding AddCommand}">Add item to ListBox</Button>
ScrollToLastItemBehavior:
public class ScrollToLastItemBehavior : Behavior<ListBox>
{
protected override void OnAttached()
{
var listBox = AssociatedObject;
((INotifyCollectionChanged)listBox.Items).CollectionChanged += OnListBox_CollectionChanged;
}
protected override void OnDetaching()
{
var listBox = AssociatedObject;
((INotifyCollectionChanged)listBox.Items).CollectionChanged -= OnListBox_CollectionChanged;
}
private void OnListBox_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
var listBox = AssociatedObject;
if (listBox.Items.Count > 0)
{
var lastItem = listBox.Items[listBox.Items.Count - 1];
listBox.ScrollIntoView(lastItem);
}
}
}
Во VieModel ничего особенного нет:
public class MainVm : INotifyPropertyChanged
{
public MainVm()
{
AddCommand = new RelayCommand(AddItem);
}
public ObservableCollection<string> Items { get; set; } = new ObservableCollection<string>();
public ICommand AddCommand { get; set; }
private void AddItem()
{
Items.Add("Current time: " + DateTime.Now.ToString("hh:mm:ss.fff tt"));
}
#region INPC
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion INPC
}
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости