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

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

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

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

スクロール

スクロールとは、ディスプレイスクリーン上において連続的にコンテンツが滑っていくことを指します。

WPF

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

Q&A

解決済

1回答

1091閲覧

ListViewの表示データが0件になった場合スクロールがコントロール出来ない

ggiilliigg

総合スコア1

C#

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

スクロール

スクロールとは、ディスプレイスクリーン上において連続的にコンテンツが滑っていくことを指します。

WPF

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

1グッド

0クリップ

投稿2021/05/06 02:49

編集2021/05/07 00:08

前提・実現したいこと

C#とWPFにてアプリを作成しております。
対象データごとに詳細データを確認、追加、編集出来るページがあるのですが、詳細データListView部分のスクロールのコントロールが上手くいかない部分があります。
対象データを変更するごとに詳細データの横スクロールを初期値(1番左)へ戻したいです。

発生している問題

詳細データを保持している対象データを表示する

詳細データの横スクロールを1番右へ移動させる

表示されている詳細データを削除する

詳細データを保持していない対象データを表示する

詳細データを追加するとスクロールが右位置のまま表示される
遷移先の対象データが詳細データを保持していればスクロールは初期値(1番左)へ戻っている

といった状態です。

該当のソースコード

C#側で対象データが変わる際に通るようScrollToHomeは実装しています。

補足情報

VisualStudio2013で実装。
調査を進めてデータがないとスクロールコントロールが出来ないように思った。

データがない場合でもスクロールをコントロール出来るよう実装したいです。
どなたかご教示お願いいたします。

TN8001👍を押しています

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

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

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

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

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

y_waiwai

2021/05/06 02:50

質問文は編集できます 追記修正しましょう
guest

回答1

0

ベストアンサー

詳細データを追加するとスクロールが右位置のまま表示される

うまく日本語で説明できませんが、ListViewItemsSourceをまたがってスクロール位置を保存しているということですよね?

なぜかアイテムが空の時に限って、水平スクロールバーも出ないし左端に寄って表示する。
そこでアイテムが追加されると、保存された位置にスクロールされる。
これ自体はちょっと変ですが標準の動作ですね。

C#側で対象データが変わる際に通るようScroll ToHomeは実装しています。

これのことでしょうか?
ScrollViewer.ScrollToHome Method (System.Windows.Controls) | Microsoft Docs

このちょっと変な動作をキャンセルするために、選択が変わるたびにScrollToHomeしているが「アイテムが空の時だけは効かない」と。

私もよくわかりませんが、これに該当するということなんでしょう。

This method does not induce any scrolling behavior if ScrollInfo is null.

単純にやるならアイテムの追加時にもScrollToHomeしたらどうですか?
(確かに「位置を保存しないオプション」があってもいいですね)


今の理解での検証コード(全然違うという場合はもっと詳しく説明してください)

xml

1<Window 2 x:Class="Questions336796.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="800" 6 Height="450"> 7 <Grid> 8 <Grid.ColumnDefinitions> 9 <ColumnDefinition /> 10 <ColumnDefinition Width="Auto" /> 11 <ColumnDefinition /> 12 </Grid.ColumnDefinitions> 13 <ListBox 14 x:Name="listBox" 15 DisplayMemberPath="Name" 16 ItemsSource="{Binding Items}" 17 SelectionChanged="ListBox_SelectionChanged" /> 18 <StackPanel Grid.Column="1"> 19 <Button Click="AddButton_Click" Content="詳細追加" /> 20 <Button Click="ClearButton_Click" Content="詳細全削除" /> 21 <CheckBox 22 x:Name="checkBox1" 23 Content="ScrollToHome" 24 IsChecked="True" /> 25 <CheckBox 26 x:Name="checkBox2" 27 Content="Virtualizing" 28 IsChecked="True" /> 29 </StackPanel> 30 <ListView 31 x:Name="listView" 32 Grid.Column="2" 33 ItemsSource="{Binding SelectedItem.Details, ElementName=listBox}" 34 VirtualizingPanel.IsVirtualizing="{Binding IsChecked, ElementName=checkBox2}"> 35 <ListView.View> 36 <GridView> 37 <GridViewColumn 38 Width="200" 39 DisplayMemberBinding="{Binding Detail1}" 40 Header="詳細1" /> 41 <GridViewColumn 42 Width="200" 43 DisplayMemberBinding="{Binding Detail2}" 44 Header="詳細2" /> 45 <GridViewColumn 46 Width="200" 47 DisplayMemberBinding="{Binding Detail3}" 48 Header="詳細3" /> 49 </GridView> 50 </ListView.View> 51 </ListView> 52 </Grid> 53</Window>

cs

1using System; 2using System.Collections.Generic; 3using System.Collections.ObjectModel; 4using System.Linq; 5using System.Windows; 6using System.Windows.Controls; 7using System.Windows.Media; 8 9namespace Questions336796 10{ 11 public partial class MainWindow : Window 12 { 13 public ObservableCollection<Item> Items { get; } 14 15 public MainWindow() 16 { 17 InitializeComponent(); 18 19 Items = new ObservableCollection<Item> 20 { 21 new Item { Name = "Item1", }, 22 new Item { Name = "Item2", }, 23 new Item { Name = "Item3", }, 24 }; 25 Items[0].Details.Add(new Detail()); 26 Items[2].Details.Add(new Detail()); 27 28 DataContext = this; 29 } 30 31 private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 32 { 33 if (checkBox1.IsChecked == true) 34 { 35 var sv = listView.Descendants<ScrollViewer>().First(); 36 sv.ScrollToHome(); 37 } 38 } 39 40 private void AddButton_Click(object sender, RoutedEventArgs e) 41 { 42 if (listBox.SelectedItem is Item item) 43 item.Details.Add(new Detail()); 44 45 if (checkBox1.IsChecked == true) 46 { 47 var sv = listView.Descendants<ScrollViewer>().First(); 48 sv.ScrollToHome(); 49 } 50 } 51 52 private void ClearButton_Click(object sender, RoutedEventArgs e) 53 { 54 if (listBox.SelectedItem is Item item) 55 item.Details.Clear(); 56 } 57 } 58 59 public class Item 60 { 61 public string Name { get; set; } 62 public ObservableCollection<Detail> Details { get; } = new ObservableCollection<Detail>(); 63 } 64 65 public class Detail 66 { 67 public string Detail1 { get; set; } = "Detail1"; 68 public string Detail2 { get; set; } = "Detail2"; 69 public string Detail3 { get; set; } = "Detail3"; 70 } 71 72 // [VisualTreeの子孫要素を取得する - xin9le.net](https://blog.xin9le.net/entry/2013/10/29/222336) 73 public static class DependencyObjectExtensions 74 { 75 //--- 子要素を取得 76 public static IEnumerable<DependencyObject> Children(this DependencyObject obj) 77 { 78 if (obj == null) throw new ArgumentNullException(nameof(obj)); 79 80 var count = VisualTreeHelper.GetChildrenCount(obj); 81 if (count == 0) yield break; 82 83 for (var i = 0; i < count; i++) 84 { 85 var child = VisualTreeHelper.GetChild(obj, i); 86 if (child != null) yield return child; 87 } 88 } 89 90 //--- 子孫要素を取得 91 public static IEnumerable<DependencyObject> Descendants(this DependencyObject obj) 92 { 93 if (obj == null) throw new ArgumentNullException(nameof(obj)); 94 95 foreach (var child in obj.Children()) 96 { 97 yield return child; 98 foreach (var grandChild in child.Descendants()) 99 yield return grandChild; 100 } 101 } 102 103 //--- 特定の型の子要素を取得 104 public static IEnumerable<T> Children<T>(this DependencyObject obj) 105 where T : DependencyObject => obj.Children().OfType<T>(); 106 107 //--- 特定の型の子孫要素を取得 108 public static IEnumerable<T> Descendants<T>(this DependencyObject obj) 109 where T : DependencyObject => obj.Descendants().OfType<T>(); 110 } 111}

仮想化を切っても(回答コードで両方のチェックを外す)似たような動きになりましたが、これはちょっとイヤですかねぇ。

投稿2021/05/06 09:25

編集2023/07/26 16:25
TN8001

総合スコア9317

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

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

ggiilliigg

2021/05/07 00:10

拙い質問内容にも関わらずご回答ありがとうございました。 まさしくその通りです。 頂いた内容を元に修正してみます。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問