質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

2回答

9744閲覧

[WPF] 複数のListViewのスクロールバーを同期させたい。

paul

総合スコア21

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2017/06/29 10:26

###前提・実現したいこと
WPFアプリケーションを作成しています。
二つのListViewを持つアプリケーションですが、二つのListViewのスクロールバーの挙動を同期させたいと考えています。
※片方がスクロールしたらもう片方も同時にスクロールするイメージです。

WPFのScrollViewerやScrollBarのスクロール位置を同期させる
上記の記事を参考に実装を進めています。

しかし、XAMLの知識が浅いためなのか、うまく同期させられず困っております。

###ソース

※Behaviorは、とりあえず上記の記事をそのまま使わせていただいております。

###1.下記ソースではスクロール同期はされない。

<Grid Grid.Column="0"> <ListView Margin="10,41,5,30" ItemsSource="{Binding ViewA}"> <ListView.ItemContainerStyle> <Style TargetType="{x:Type ListViewItem}"> <Style.Triggers> <DataTrigger Binding="{Binding IsDiff}" Value="true"> <Setter Property="Background" Value="#ffc8c8" /> </DataTrigger> </Style.Triggers> </Style> </ListView.ItemContainerStyle> <ListView.View> <GridView> <GridViewColumn DisplayMemberBinding="{Binding A}" Header="A" /> <GridViewColumn DisplayMemberBinding="{Binding B}" Header="B" /> <GridViewColumn DisplayMemberBinding="{Binding C}" Header="C" /> <GridViewColumn DisplayMemberBinding="{Binding D}" Header="D" /> <GridViewColumn DisplayMemberBinding="{Binding E}" Header="E" /> <GridViewColumn DisplayMemberBinding="{Binding F}" Header="F" /> </GridView> </ListView.View> <i:Interaction.Behaviors> <b:ScrollSyncronizingBehavior ScrollGroup="Group1" Orientation="Vertical" /> </i:Interaction.Behaviors> </ListView> </Grid> <Grid Grid.Column="1"> <ListView Margin="5,41,10,30" ItemsSource="{Binding ViewB}"> <ListView.ItemContainerStyle> <Style TargetType="{x:Type ListViewItem}"> <Style.Triggers> <DataTrigger Binding="{Binding IsDiff}" Value="true"> <Setter Property="Background" Value="#ffc8c8" /> </DataTrigger> <DataTrigger Binding="{Binding IsNone}" Value="true"> <Setter Property="Background" Value="#606060" /> </DataTrigger> </Style.Triggers> </Style> </ListView.ItemContainerStyle> <ListView.View> <GridView> <GridViewColumn DisplayMemberBinding="{Binding A}" Header="A" /> <GridViewColumn DisplayMemberBinding="{Binding B}" Header="B" /> <GridViewColumn DisplayMemberBinding="{Binding C}" Header="C" /> <GridViewColumn DisplayMemberBinding="{Binding D}" Header="D" /> <GridViewColumn DisplayMemberBinding="{Binding E}" Header="E" /> <GridViewColumn DisplayMemberBinding="{Binding F}" Header="F" /> </GridView> </ListView.View> <i:Interaction.Behaviors> <b:ScrollSyncronizingBehavior ScrollGroup="Group1" Orientation="Vertical" /> </i:Interaction.Behaviors> </ListView> </Grid>

###2.ScrollViewerを中で定義してそこにビヘイビアを仕掛けてみるも、XamlParseExceptionが発生

<Grid Grid.Column="0"> <ListView Margin="10,41,5,30" ItemsSource="{Binding ViewA}"> <ListView.ItemContainerStyle> <Style TargetType="{x:Type ListViewItem}"> <Style.Triggers> <DataTrigger Binding="{Binding IsDiff}" Value="true"> <Setter Property="Background" Value="#ffc8c8" /> </DataTrigger> </Style.Triggers> </Style> </ListView.ItemContainerStyle> <ListView.View> <GridView> <GridViewColumn DisplayMemberBinding="{Binding A}" Header="A" /> <GridViewColumn DisplayMemberBinding="{Binding B}" Header="B" /> <GridViewColumn DisplayMemberBinding="{Binding C}" Header="C" /> <GridViewColumn DisplayMemberBinding="{Binding D}" Header="D" /> <GridViewColumn DisplayMemberBinding="{Binding E}" Header="E" /> <GridViewColumn DisplayMemberBinding="{Binding F}" Header="F" /> </GridView> </ListView.View> <ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"> <i:Interaction.Behaviors> <b:ScrollSyncronizingBehavior ScrollGroup="Group1" Orientation="Vertical" /> </i:Interaction.Behaviors> </ScrollViewer> </ListView> </Grid> <Grid Grid.Column="1"> <ListView Margin="5,41,10,30" ItemsSource="{Binding ViewB}"> <ListView.ItemContainerStyle> <Style TargetType="{x:Type ListViewItem}"> <Style.Triggers> <DataTrigger Binding="{Binding IsDiff}" Value="true"> <Setter Property="Background" Value="#ffc8c8" /> </DataTrigger> <DataTrigger Binding="{Binding IsNone}" Value="true"> <Setter Property="Background" Value="#606060" /> </DataTrigger> </Style.Triggers> </Style> </ListView.ItemContainerStyle> <ListView.View> <GridView> <GridViewColumn DisplayMemberBinding="{Binding A}" Header="A" /> <GridViewColumn DisplayMemberBinding="{Binding B}" Header="B" /> <GridViewColumn DisplayMemberBinding="{Binding C}" Header="C" /> <GridViewColumn DisplayMemberBinding="{Binding D}" Header="D" /> <GridViewColumn DisplayMemberBinding="{Binding E}" Header="E" /> <GridViewColumn DisplayMemberBinding="{Binding F}" Header="F" /> </GridView> </ListView.View> <ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"> <i:Interaction.Behaviors> <b:ScrollSyncronizingBehavior ScrollGroup="Group1" Orientation="Vertical" /> </i:Interaction.Behaviors> </ScrollViewer> </ListView> </Grid>

###発生している問題・エラーメッセージ

上記2のエラー

System.Windows.Markup.XamlParseException が発生しました

HResult=0x80131501
Message='型 'System.Windows.Controls.ItemCollection' のコレクションに値を追加しているときに例外がスローされました。' 行番号 '68'、行位置 '7'。
Source=PresentationFramework
スタック トレース:
at System.Windows.Markup.XamlReader.RewrapException(Exception e, IXamlLineInfo lineInfo, Uri baseUri)
内部例外 1:
InvalidOperationException: ItemsSource が使用中の場合、操作は無効です。代わりに ItemsControl.ItemsSource を使用して要素にアクセスし、変更してください。

###試したこと
テンプレート?を使ってScrollViewerもしくはScrollBarを自分で定義して、その中にBehaviorを仕掛けるみたいなことを考えましたが、実行時に、ItemXamlParseExceptionが発生してしまいます。
ScrollViewerを定義したことで、GridViewColumnの定義自体がなくなってしまっている??のでしょうか。

###補足情報(言語/FW/ツール等のバージョンなど)
それぞれのListViewにはGridViewColumnを定義しています。
ViewModelに定義してあるDataViewをItemsSourceにバインドしています。
基本的にMVVMに準拠しつつ作成を進めています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

単純に、「ListViewに中身のItemsSourceがあるのに、ScrollViewerを入れるな」というエラーですね。

ListViewは、ScrollViewerを中に持っているので、

[WPF]ScrollViewerが入れ子のときマウススクロールが効かない問題への対処法

の感じで、ListViewのScrollViewerを無くして、ListViewをScrollViewerを囲むとうまくいくのかな?(やっていない)

もしくは、ビヘイビアの方を、
Accessing the ScrollViewer of a ListBox from C#
これに対応させる形で改造する。

ビヘイビアは何回も使うなら便利だけど、一回しか使わないようなものだと、
大して便利ではないという印象なので、わたしなら、コードビハインドでやってしまうかな。
ビヘイビアは、結局コードビハインドでやっていることをやるので。(結構複雑な形で)

投稿2017/06/29 11:26

kiichi54321

総合スコア1984

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

paul

2017/06/30 04:32 編集

回答ありがとうございます。 おっしゃる通り、確かに「ListViewのScrollViewerを無くして、ListViewをScrollViewerを囲む」と、二つのListViewが同期して動くことを確認しました。 ありがとうございます。 理解力不足で申し訳ありませんが、XAMLの理解を深めたいため、質問させてください。 ・ListViewにScrollViewerを新たに含めようとするとエラーが起こることがわかりましたが、「ListViewに中身のItemsSourceがあるのに、ScrollViewerを入れるな」の理由が未だわかっておりません。 ・ListView自体が持っているScrollViewerにビヘイビアを効かせることはできますでしょうか。 また、以下より相談です。 ListViewがデータの大きさによって現在の表示領域外まで広がるようになりました。 (ScrollViewerは、中身のコンテンツ(今回でいうとListViewにバインドしているデータ)が外側の枠組みで表示しきれなかった場合、スクロール領域を用意し表示可能にするものですので当たり前といえば当たり前なのですが)ListViewの大きさはデータの行数によって動的に変化し、現在の表示領域以上の大きさになる、その大きいListViewコンテンツ全体をスクロールしてあげる状態になった状態といえます。しかしその状態でスクロールするとカラムヘッダーが隠れてしまいます。 また、バインドしたデータのカラムが大きかった場合でも、横幅は自動的に広がらないため、今回用意したScrollViewerの水平方向のスクロールバーが現れません。(また、これはビヘイビアの問題な気がしますが、ListView自体のスクロールバーを動かそうと思っても正しいスクロールバーの動作をしません。) また、バインドしている最中、非常に動作が重くなります。ListViewのUIのHeightがバインド中常に増加して再描画が発生しているからなのかとにらんでいます。Heightを固定幅にしたら重い動作が改善されました。 これを以前のListViewの中に存在するScrollViewerのようなものに近づけたく思っております。 よろしくお願いいたします。
guest

0

自己解決

自己解決しましたので報告いたします。

ListView自体が持っているScrollViewerにビヘイビアを効かせることができました。

XAML

1 2 <Style x:Key="ListViewScrollSyncStyle" TargetType="{x:Type ListView}"> 3 <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" /> 4 <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" /> 5 <Setter Property="ScrollViewer.CanContentScroll" Value="true" /> 6 <Setter Property="ScrollViewer.PanningMode" Value="Both" /> 7 <Setter Property="Stylus.IsFlicksEnabled" Value="False" /> 8 <Setter Property="VerticalContentAlignment" Value="Center" /> 9 <Setter Property="Template"> 10 <Setter.Value> 11 <ControlTemplate TargetType="{x:Type ListView}"> 12 <Themes:ListBoxChrome 13 x:Name="Bd" 14 Background="{TemplateBinding Background}" 15 BorderBrush="{TemplateBinding BorderBrush}" 16 BorderThickness="{TemplateBinding BorderThickness}" 17 RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" 18 RenderMouseOver="{TemplateBinding IsMouseOver}" 19 SnapsToDevicePixels="true"> 20 <ScrollViewer Padding="{TemplateBinding Padding}" Style="{DynamicResource {x:Static GridView.GridViewScrollViewerStyleKey}}"> 21 <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> 22 <!-- ビヘイビア --> 23 <i:Interaction.Behaviors> 24 <b:ScrollSyncronizingBehavior Orientation="Vertical" ScrollGroup="Group_V" /> 25 <b:ScrollSyncronizingBehavior Orientation="Horizontal" ScrollGroup="Group_H" /> 26 </i:Interaction.Behaviors> 27 <!-- ビヘイビア --> 28 </ScrollViewer> 29 </Themes:ListBoxChrome> 30 <ControlTemplate.Triggers> 31 <Trigger Property="IsEnabled" Value="false"> 32 <Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" /> 33 </Trigger> 34 <MultiTrigger> 35 <MultiTrigger.Conditions> 36 <Condition Property="IsGrouping" Value="true" /> 37 <Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false" /> 38 </MultiTrigger.Conditions> 39 <Setter Property="ScrollViewer.CanContentScroll" Value="false" /> 40 </MultiTrigger> 41 </ControlTemplate.Triggers> 42 </ControlTemplate> 43 </Setter.Value> 44 </Setter> 45 </Style>

Styleを定義して、そのStyle内でControlTemplateを定義し、ListViewのスクロールバーにビヘイビアを効かせることができました。

また、水平方向スクロールバーが正しく動作しなかったのは、XAML側(使用する側)のビヘイビアの記述の仕方で水平方向の行が不足していたことが原因でした。

投稿2017/06/30 05:22

paul

総合スコア21

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問