2011-08-21 10 views
5

私はMedia Assistantという名前のopensourceアプリケーションを開発しています。ライブラリを表示するためにListBoxを使用しました。 ItemsSourceは、LibraryItemのリストにバインドされています。ここにXALMがあります。ステータスメッセージを変更したり、待機画面を表示したりすると、WPF ListBoxがスクロールします

<ListBox Name="Tree" DockPanel.Dock="Top" 
    ItemsSource="{Binding DataSource.OrderedLibraryItems}" 
    Background="{StaticResource LibraryBackground}" 
    Width="220" HorizontalAlignment="Left" 
    BorderThickness="0" 
    VirtualizingStackPanel.IsVirtualizing="True" 
    VirtualizingStackPanel.VirtualizationMode="Standard" 
    ScrollViewer.IsDeferredScrollingEnabled="True" 
    ItemTemplate="{StaticResource ListLibraryItemTemplate}" 
    SelectionMode="Single" 
    MouseDoubleClick="HandleMouseDoubleClick" 
/> 

Dispatcherを使用してスレッドからウィンドウの下部にステータスメッセージを表示すると問題が発生します。

Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,new ParameterizedThreadStart(action), state); 

リストボックスが上部にスクロールします。ステータスメッセージが表示されない場合は正常に動作します。 datacontextまたはリストアイテムまたはフォーカスは変更されていません。なぜそれがそれをしているのかわからなかった。これは、モーダルでないウィンドウである待機画面を表示するときに発生します。私は別のプロジェクトでそれを再現できませんでした。 HereはMedia Assistantのソースコードです。 BackgroundScannerクラスのメソッドSetStatusMessageのreturn文をコメント解除することで簡単に再作成できます。

+0

醜い作業の回避策です。インデックスが-1の場合、0を表示しようとしました。私はDispatcherメッセージを使用していませんでしたが、ListBoxの上にTextBlockを置くと、私は運が良かったのですが、リストビューで私はより良い動作を得ました。 ListBoxは高速で、私はそれが好きですが、私が理解していないものはいくつかあります。遅延スクロールなしで同じ動作をしますか?バインディングモードがonewayの場合、宣言します。 – Paparazzi

答えて

3

私はこれの背後にある理由を見つけました。解決策です。 DockPanelを使用してUIをレイアウトしました。ステータスバーを下に、ListBoxを左に、その他のアイテムは中と上に配置します。 StatusBarには幅と高さがAutoに設定されているTextBlockがあります。したがって、ステータスバーTextBlockのテキストを変更すると、幅と高さが再計算され、親のレイアウトが再計算されます。したがって、ListBoxはMeasuresおよびArrangeに呼び出されます。サイズは変更されませんが、スクロール位置が上にリセットされます。これは、ListBoxでScrollViewer.CanContentScroll = "True"を使用する場合にのみ発生します。デフォルトではTrueです。だから、私はこの値を設定していなくてもスクロール位置をリセットしていました。 ScrollViewer.CanContentScroll = "False"を使用して無効にすると、正常に動作します。

<ListBox Name="Tree" DockPanel.Dock="Top" 
    ItemsSource="{Binding DataSource.OrderedLibraryItems}" 
    Background="{StaticResource LibraryBackground}" 
    Width="220" HorizontalAlignment="Left" 
    BorderThickness="0" 
    VirtualizingStackPanel.IsVirtualizing="True" 
    VirtualizingStackPanel.VirtualizationMode="Standard" 
    ScrollViewer.IsDeferredScrollingEnabled="True" 
    ScrollViewer.CanContentScroll="False" 
    ItemTemplate="{StaticResource ListLibraryItemTemplate}" 
    SelectionMode="Single" 
    MouseDoubleClick="HandleMouseDoubleClick" 
/> 

しかしScrollViewer.CanContentScrollは=「false」を設定するには、仮想化を無効にし、私は私がのTextBlockに固定高さと幅を設定するので、私のリストボックスに仮想化を使用します。したがって、DockPanelはステータスメッセージを変更すると、その子を再配置しません。

ScrollViewerのバグかもしれません。サイズが変更されていない場合、スクロール位置は変更しないでください。

+0

あなたの答えは回避策です。それは証明された説明がないことを意味し、この解決策は誰にとっても合わないかもしれません。人々が本当の解決策をまだ投稿できるように、「回答を解決する質問」フラグをオフにしてもよいですか?私は同じ問題を抱えており、アプリケーションの次元を修正することはできません。 – SandRock

+0

「解決策」がポスターに適している場合は、チェックする必要があります。他のユーザーは、より良い(この場合は「実際の修正」)回答を提供し、より良い解決策を提供したいと思うかもしれませんが、それが私が考える仕組みです。私は私の答えが5つのアップフォートを持っている1つのケースがありますが、 "正しい、チェックされた"答えは1つしかありませんでした。 –

+0

ねえ、そうです。私は代わりに賞金を掲示しました:) – SandRock

-1

レイアウトがリセットされているので、最初の項目(0)を選択するリストボックスが必要です。

リストボックス内の既存の項目の数を選択した項目を設定してみてください:

Tree.SelectedIndex = Tree.Items.Count; 

私はあなたのコードでこのソリューションをテストしていないが、私はどこ私の別のプロジェクトでそれを使用しています私も同様の問題がありました。

希望します。

+0

あなたの答えをありがとう。 WPFは、サイズ変更が発生したときに最初の項目を実際に選択していません。スクロールビューワの垂直オフセットと水平オフセットをリセットするだけです。問題が発生すると、私はユーザーの選択を変更せず、スクロールビューアがゼロにリセットされないようにします。申し訳ありませんが、あなたのソリューションには望ましくない副作用(選択の変更)があります。 – SandRock

+0

私の間違い、それはひどく分かりました。副作用を防止するために、選択されたアイテム配列は、「リフレッシュ」が発生した後に記憶され、リセットされ得る。とにかくそれは問題の解決策ではありません。 – Pimenta

0

これを試してみてください:返信で

listBox1.ScrollIntoView(listBox1.Items.GetItemAt(listBox1.Items.Count - 1)); 
+0

あなたのコードは、ListBoxのScrollViewerを最後の項目までスクロールさせます。私はスクロールビューワが以前の位置(ゼロからN-1までの範囲であってもよい)に留まることを望みます。 – SandRock

0

を@ user904627の答えに、ここで彼の回避策の拡張版です。 WidthHeightを固定するだけの問題は、ユーザーがウィンドウのサイズを変更してもListBoxが同じ位置を保持することです。これは受け入れられません。私は幅と高さを修正したが、時にコンテナのサイズが変更リストボックス自体のサイズを変更できるように親要素のSizeChangedイベントにリッスンこの小さな行動を作成した理由

です。

コードはここにある:VirtualizedListBoxFixBehavior

親要素のサイズが変更された場合、私はdouble.NaNWidthHeightを復元(SOコントロール自体のサイズを変更することができる)と私は、実際のサイズ特性を修正コードのビットをキュー後で実行するためにDispatcherの値。

しかし、これはまだ私は似たようなを持っていたと私は理解することができ、すべてのビューで選択した項目をUIをしたかったです...

関連する問題