![](/img/trans.png)
[英]How do I bind controls to the selected item in a listbox using WPF and the MVVM pattern?
[英]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.