簡體   English   中英

WPF,如何使用MVVM模式觸發ListBox.ScrollIntoView?

[英]WPF, how do I trigger ListBox.ScrollIntoView using MVVM pattern?

我有一個WPF應用程序,當用戶按下按鈕時,ListBox的內容就會更新。 我最初的問題是將ListBox重新聚焦到特定的SelectedIndex值,該值綁定到ViewModel中的ActiveItem屬性。 我可以使用以下代碼解決此問題:

XAML:

<ListBox ItemsSource="{Binding ListOfItems}" SelectedIndex="{Binding ActiveItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                 IsSynchronizedWithCurrentItem="True"  SelectionChanged="ListBox_SelectionChanged" x:Name="ListBoxSelector">

代碼隱藏:

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        ListBoxSelector.ScrollIntoView(ListBoxSelector.SelectedItem);
    }

但是,我目前在MainWindow.xaml.cs文件而不是ViewModel中具有上面的代碼。 我的問題是如何將這段代碼移至ViewModel,以便堅持使用MVVM模式? 我還不太清楚如何從ViewModel正確處理ListBox的ScrollIntoView屬性。

您可以使用Behavior類強制選定的項目滾動到視圖中。

public class perListBoxHelper : Behavior<ListBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.SelectionChanged -= AssociatedObject_SelectionChanged;
        base.OnDetaching();
    }

    private static void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var listBox = sender as ListBox;

        if (listBox?.SelectedItem == null)
            return;

        Action action = () =>
        {
            listBox.UpdateLayout();

            if (listBox.SelectedItem != null)
                listBox.ScrollIntoView(listBox.SelectedItem);
        };

        listBox.Dispatcher.BeginInvoke(action, DispatcherPriority.ContextIdle);
    }
}

有關我的博客文章的更多詳細信息。

另外,我個人倒綁定到SelectedItem的列表框,而不是SelectedIndex ,以及處理項目選擇的任何處理該財產二傳手,而不是使用事件處理程序。

MVVM模式不排除使用后面的代碼。 實際上,這不可能,因為在某些情況下, 正確的做法是隱藏背后代碼。 視圖模型是一個模型,不是視圖替換。 另一種思考方式是,視圖模型包含內容 ,而視圖包含方式 至少,這是我對MVVM模式的解釋。

在你的情況下,是什么項目的列表和當前項目。 該是怎樣ListBox本身和它的默認行為。 在我看來,將選定的項目滾動到視圖中是一種額外的行為,因此應保留在視圖中。 因為你保持什么視圖模型和如何在視圖中你不違反MVVM模式。

我不確定我的解決方案是否為MVVM模式。但是對於這樣的問題,它可以解決問題。

我將執行以下操作:如果按下Button,它將觸發一個命令調用ViewModel中的方法。當ViewModel完成其工作時,viewModel會拋出一個自定義事件(其中包括列表框應滾動到的項目索引)。 在此之前,加載View時,View的Code-behind應該通過View的DataContext偵聽其ViewModel,然后執行scrollIntoView。

就像我說的那樣,我不確定這是否是MVVM,但是我認為這是可以接受的。

沒有針對每個請求的通用解決方案,正如其他人提到的那樣,MVVM並不意味着沒有代碼,但也沒有多余的代碼。

但是,如果您不想要任何代碼,則可以在您的特定請求中找到解決方案-創建一個從ListView繼承並按需要處理請求的類,然后在XAML中使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM