[ WPF ListBox ]를 [Selected]으로 스크롤합니다.뷰 모델의 코드에 설정된 항목
목록 상자가 있는 XAML 뷰가 있습니다.
<control:ListBoxScroll ItemSource="{Binding Path=FooCollection}"
SelectedItem="{Binding SelectedFoo, Mode=TwoWay}"
ScrollSelectedItem="{Binding SelectedFoo}">
<!-- data templates, etc. -->
</control:ListBoxScroll>
선택한 항목은 내 보기에 속성에 바인딩되어 있습니다.사용자가 목록 상자에서 항목을 선택하면 뷰 모델의 SelectedFoo 속성이 업데이트됩니다.뷰 모델에서 SelectedFoo 속성을 설정하면 목록 상자에서 올바른 항목이 선택됩니다.
Foo가 되지 않는 Selected Foo를 입니다.ScrollIntoView
목록 상자에 있습니다.List Box list list 、 list list list list 、 list list list...나는 그것을 할 수 있는 편리한 방법을 찾을 수 없었다.리스트 박스 스크롤
class ListBoxScroll : ListBox
{
public static readonly DependencyProperty ScrollSelectedItemProperty = DependencyProperty.Register(
"ScrollSelectedItem",
typeof(object),
typeof(ListBoxScroll),
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(onScrollSelectedChanged)));
public object ScrollSelectedItem
{
get { return (object)GetValue(ScrollSelectedItemProperty); }
set { SetValue(ScrollSelectedItemProperty, value); }
}
private static void onScrollSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var listbox = d as ListBoxScroll;
listbox.ScrollIntoView(e.NewValue);
}
}
속성을 합니다.ScrollSelectedItem
는 그것을 내내 에 묶는다.SelectedFoo
뷰 모델에 속성을 표시합니다.그런 다음 종속 속성의 변경된 속성 콜백에 연결하고 새로 선택한 항목을 보기로 스크롤합니다.
뷰 모델을 기반으로 한 XAML 뷰에서 사용자 컨트롤에 대한 함수를 호출하는 더 쉬운 방법을 알고 있는 사람이 있습니까?다음 작업을 수행하기에는 다소 번거롭습니다.
- 종속 속성을 생성하다
- 속성 변경 콜백에 콜백 추가
- 스태틱 콜백 내의 함수 호출 처리
'이론'에 것 요.ScrollSelectedItem { set {
그러나 종속 프레임워크는 실제로 전화를 받지 않고 작업하는 것 없이 작업하는 것 같다.메서드는 의존관계 프레임워크가 실제로 호출하지 않고 슬쩍 돌아다니는 것처럼 보입니다.
동작을 사용해 본 적이 있습니까?다음은 Scroll In View Behavior 입니다.ListView 및 DataGrid에 사용하고 있습니다.ListBox에서 작동해야 할 것 같은데...
You have to add a reference to 참조를 추가해야 합니다.System.Windows.Interactivity
to use 사용하다Behavior<T> class
행동
public class ScrollIntoViewForListBox : Behavior<ListBox>
{
/// <summary>
/// When Beahvior is attached
/// </summary>
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged;
}
/// <summary>
/// On Selection Changed
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void AssociatedObject_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
if (sender is ListBox)
{
ListBox listBox = (sender as ListBox);
if (listBox .SelectedItem != null)
{
listBox.Dispatcher.BeginInvoke(
(Action) (() =>
{
listBox.UpdateLayout();
if (listBox.SelectedItem !=
null)
listBox.ScrollIntoView(
listBox.SelectedItem);
}));
}
}
}
/// <summary>
/// When behavior is detached
/// </summary>
protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.SelectionChanged -=
AssociatedObject_SelectionChanged;
}
}
사용.
Add alias to 에 별칭 추가XAML
as ~하듯이xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
then in your 그럼 네 안에Control
<ListBox ItemsSource="{Binding Path=MyList}"
SelectedItem="{Binding Path=MyItem,
Mode=TwoWay}"
SelectionMode="Single">
<i:Interaction.Behaviors>
<Behaviors:ScrollIntoViewForListBox />
</i:Interaction.Behaviors>
</ListBox>
이제 "내 항목" 속성은 "내 항목" 정 우 된 이 성 now when is " " ever경설my속 property in setmy"item" 내 항목" 속성) 속성) 속성"로 설정ViewModel
변경 내용이 선택되면 목록이 스크롤됩니다.
답변을 검토한 후 ListBox의 SelectionChanged 이벤트를 청취하는 외부 클래스가 공통의 테마를 제시했습니다.그 결과 의존적인 자산 접근법이 너무 지나쳤다는 것을 깨달았습니다.그리고 서브클래스가 자기 의견을 듣게 할 수 있었습니다.
class ListBoxScroll : ListBox
{
public ListBoxScroll() : base()
{
SelectionChanged += new SelectionChangedEventHandler(ListBoxScroll_SelectionChanged);
}
void ListBoxScroll_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ScrollIntoView(SelectedItem);
}
}
이것이 내가 원하는 것을 할 수 있는 가장 간단한 해결책이라고 생각한다.
명예로운 언급은 행동을 제기한 adcool2007에 돌아간다.다음은 관심 있는 사용자를 위한 몇 가지 기사입니다.
http://blogs.msdn.com/b/johngossman/archive/2008/05/07/the-attached-behavior-pattern.aspx
http://www.codeproject.com/KB/WPF/AttachedBehaviors.aspx
몇 가지 다른 사용자 컨트롤에 추가되는 일반적인 행동(예: 클릭 동작, 드래그 동작, 애니메이션 동작 등)의 경우 부가적인 행동이 매우 타당하다고 생각합니다.이되어 있기 입니다.ScrollIntoView
에 대해 할 수 .) ListBox는 ListBox 이외의 컨트롤에 대해 발생할 수 있습니다.
이는 보기 문제이기 때문에 이 목적을 위해 보기 뒤에 있는 코드에 이벤트 핸들러를 사용하지 못할 이유가 없습니다.를 들어주세요.ListBox.SelectionChanged
새로 선택한 항목을 보기로 스크롤할 때 사용합니다.
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
((ListBox)sender).ScrollIntoView(e.AddedItems[0]);
}
된 것은 ListBox
이 일을 하기 위해서., 이이 필요할 때 사용하세요.ListBox.SelectedItem
값이 변경되면(원래 질문에서 설명한 대로), 위의 핸들러가 실행되고 항목이 보기로 스크롤됩니다.
<ListBox
ItemsSource="{Binding Path=FooCollection}"
SelectedItem="{Binding Path=SelectedFoo}"
SelectionChanged="ListBox_SelectionChanged"
/>
하나의 은 '를 '부속하다'로 '하다'를 입니다.ICollectionView.CurrentChanged
를 호출합니다.ListBox.ScrollIntoView
현재 새 항목에 대한 것입니다.여러 목록 상자에 이 기능이 필요한 경우 이 방법은 더 "재사용 가능한" 방법입니다.시작하기 위한 좋은 예를 여기서 찾을 수 있습니다.http://michlg.wordpress.com/2010/01/16/listbox-automatically-scroll-currentitem-into-view/
나는 이것을 (내 의견으로는) 명료하고 쉬운 해결책을 사용하고 있다
listView.SelectionChanged += (s, e) =>
listView.ScrollIntoView(listView.SelectedItem);
서 ''는listView
is of of of of 의 이름ListView
xaml),SelectedItem
xaml.cs 파일의 컨스트럭터에 코드가 삽입되어 있습니다.
오래된 질문인 것은 알지만, 최근 같은 문제를 찾아본 결과 이렇게 되었습니다. 어프로치를 「 SDK」에 의존해 「 SDK」라고 은 원하지 않았습니다.Behavior<T>
이 기능을 사용하지 않는 솔루션은 다음과 같습니다.
public static class ListBoxBehavior
{
public static bool GetScrollSelectedIntoView(ListBox listBox)
{
return (bool)listBox.GetValue(ScrollSelectedIntoViewProperty);
}
public static void SetScrollSelectedIntoView(ListBox listBox, bool value)
{
listBox.SetValue(ScrollSelectedIntoViewProperty, value);
}
public static readonly DependencyProperty ScrollSelectedIntoViewProperty =
DependencyProperty.RegisterAttached("ScrollSelectedIntoView", typeof (bool), typeof (ListBoxBehavior),
new UIPropertyMetadata(false, OnScrollSelectedIntoViewChanged));
private static void OnScrollSelectedIntoViewChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var selector = d as Selector;
if (selector == null) return;
if (e.NewValue is bool == false)
return;
if ((bool) e.NewValue)
{
selector.AddHandler(Selector.SelectionChangedEvent, new RoutedEventHandler(ListBoxSelectionChangedHandler));
}
else
{
selector.RemoveHandler(Selector.SelectionChangedEvent, new RoutedEventHandler(ListBoxSelectionChangedHandler));
}
}
private static void ListBoxSelectionChangedHandler(object sender, RoutedEventArgs e)
{
if (!(sender is ListBox)) return;
var listBox = (sender as ListBox);
if (listBox.SelectedItem != null)
{
listBox.Dispatcher.BeginInvoke(
(Action)(() =>
{
listBox.UpdateLayout();
if (listBox.SelectedItem !=null)
listBox.ScrollIntoView(listBox.SelectedItem);
}));
}
}
}
그리고 용도는
<ListBox ItemsSource="{Binding Path=MyList}"
SelectedItem="{Binding Path=MyItem, Mode=TwoWay}"
SelectionMode="Single"
behaviors:ListBoxBehavior.ScrollSelectedIntoView="True">
이것을 시험해 보세요.
private void lstBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
lstBox.ScrollIntoView(lstBox.SelectedItem);
}
여러 가지 방법을 묶은 결과, 다음과 같은 것이 가장 간단하고 최선의 방법이라는 것을 알게 되었다.
lstbox.Items.MoveCurrentToLast();
lstbox.ScrollIntoView(lstbox.Items.CurrentItem);
나는 Ankesh의 답변을 받아 혼합 sdk에 의존하지 않도록 했다.제 솔루션의 단점은 앱의 모든 목록 상자에 적용된다는 것입니다.단, 커스텀 클래스가 필요 없다는 장점이 있습니다.
앱 초기화 중...
internal static void RegisterFrameworkExtensionEvents()
{
EventManager.RegisterClassHandler(typeof(ListBox), ListBox.SelectionChangedEvent, new RoutedEventHandler(ScrollToSelectedItem));
}
//avoid "async void" unless used in event handlers (or logical equivalent)
private static async void ScrollToSelectedItem(object sender, RoutedEventArgs e)
{
if (sender is ListBox)
{
var lb = sender as ListBox;
if (lb.SelectedItem != null)
{
await lb.Dispatcher.BeginInvoke((Action)delegate
{
lb.UpdateLayout();
if (lb.SelectedItem != null)
lb.ScrollIntoView(lb.SelectedItem);
});
}
}
}
그러면 모든 목록 상자가 선택 항목(기본 동작으로 사용)으로 스크롤됩니다.
언급URL : https://stackoverflow.com/questions/8827489/scroll-wpf-listbox-to-the-selecteditem-set-in-code-in-a-view-model
'source' 카테고리의 다른 글
postgresql - 테이블 세트 기본값에 부울 열을 추가합니다. (0) | 2023.04.12 |
---|---|
[*a]이(가) 초과 할당되는 원인은 무엇입니까? (0) | 2023.04.12 |
jQuery를 사용하여 데이터 속성별 요소 선택 (0) | 2023.04.12 |
Bash에서 명령어 출력의 첫 번째 단어를 검색하려면 어떻게 해야 합니까? (0) | 2023.04.12 |
특정 커밋에 대한 리모트 리셋 (0) | 2023.04.12 |