- PR -

ListVIewの略表示のタイミング

1
投稿者投稿内容
extream
ベテラン
会議室デビュー日: 2005/12/26
投稿数: 83
投稿日時: 2007-05-28 10:57
よろしくお願いします。
−環境−
 Windows Vista ultimate
 VisualStadio2005

エクスプローラなどで、ListViewのカラム幅を狭めていった場合に、

 カラム文字列:あいうえお
         ↓
        あいう...

のように省略されますが、このデータを省略して表示するタイミングで他の処理を行いたいと考えています。
どのようにすれば、カラムのデータが省略されているかを知ることができるのでしょうか?

SelectedItems[0].Textでは、見た目は「あいう...」となっていても、取得する値は「あいうえお」となっていました。



よろしくお願いします。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-05-28 12:04
引用:

extreamさんの書き込み (2007-05-28 10:57) より:

このデータを省略して表示するタイミングで他の処理を行いたいと考えています。


安易な発想ですが、Windows メッセージを監視して独自のイベントを raise してみてはいかがでしょうか? カスタム コントロール化 (拡張コントロール) して、コントロール内部でタイミングを解決し、そのタイミングの公開をイベントにするということです。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
extream
ベテラン
会議室デビュー日: 2005/12/26
投稿数: 83
投稿日時: 2007-05-29 09:51
じゃんぬねっとさん、回答ありがとうございます。
返答遅れてすいません。


Windowsメッセージ監視はやったことがないので、まずは調べてみます。



アドバイスありがとうございます。
まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2007-05-30 11:54
引用:

Windowsメッセージ監視はやったことがないので、まずは調べてみます。


多分コントロールとヘッダのリサイズを監視することになると思いますが
省略表示はあくまで結果=見た目のはずですので、
「現在省略表示されるべき状態である」ということを自分で判断することになると思います。
れい
ぬし
会議室デビュー日: 2005/11/01
投稿数: 346
投稿日時: 2007-06-02 07:38
引用:

まどかさんの書き込み (2007-05-30 11:54) より:
多分コントロールとヘッダのリサイズを監視することになると思いますが
省略表示はあくまで結果=見た目のはずですので、
「現在省略表示されるべき状態である」ということを自分で判断することになると思います。



私も以前しらべました。
「現在省略表示されるべき状態である」というのを正確に判断することは
できませんでした。

「現在省略表示されるべき状態である」というのを正確に知るためには
表示される予定の文字列の長さ、表示可能な領域、
表示の際のフォントや余白の情報、
などを知る必要があります。

ListViewの中身はcomctl32.dllにありますが、
これがOSやパッチに依存します。
また、その内部で文字列を描画するときに
フォントやそのサイズを使いますが、文字列描画結果はそれに依存します。
さらに、描画時にグラフィックドライバのレンダリング機構を使うので、
それらにも依存する場合があります。

ですので、.Net Frameworkの動く環境一般で
「現在省略表示されるべき状態である」というのを
調べるのは無理でした。

Windowsメッセージを見ても見なくても、
この問題に関していえば、
手に入る情報は同じです。

完璧な解決方法は、
・OwnerDrawを使って自分で描く
・ListViewControlそのものを自分で作る
というのがありますが、お勧めしません。
やたらめんどくさいです。

私は以下のようなコードで誤魔化しました。
コード:

Private Sub Form1_Load( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Me.ListView1.View = View.Details
Me.ListView1.OwnerDraw = True
End Sub

Private Sub ListView_DrawColumnHeader( _
ByVal sender As Object, _
ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs) _
Handles ListView1.DrawColumnHeader
e.DrawDefault = True
End Sub

Private Sub ListView_DrawItem( _
ByVal sender As Object, _
ByVal e As System.Windows.Forms.DrawListViewItemEventArgs) _
Handles ListView1.DrawItem
End Sub

Private Sub ListView_DrawSubItem( _
ByVal sender As Object, _
ByVal e As System.Windows.Forms.DrawListViewSubItemEventArgs) _
Handles ListView1.DrawSubItem
Dim w As Integer
w = TextRenderer.MeasureText(e.SubItem.Text & " ", e.SubItem.Font).Width
If w + 4 > e.Bounds.Width Then
TextRenderer.DrawText( _
e.Graphics, "-", e.SubItem.Font, e.Bounds, _
e.SubItem.ForeColor, e.SubItem.BackColor)
Exit Sub
End If
e.DrawDefault = True
End Sub



TextRenderer.MeasureTextで表示されるべき文字列の長さを測って
それが表示可能な領域より大きいかどうかを判断して、
大きい場合は「-」を表示しています。
上記のコードでは、空白の細いフォントとかだとうまく動かない可能性があります。

どうしても省略されたタイミングを正確に知りたい場合は、
OwnerDraw(CustomDraw)で自分で全部描くのをお勧めします。
自分で全部描けば省略されたかどうかも自分で判断できますし。


[ メッセージ編集済み 編集者: れい 編集日時 2007-06-02 07:43 ]
extream
ベテラン
会議室デビュー日: 2005/12/26
投稿数: 83
投稿日時: 2007-06-05 20:52
まどかさん、れいさん、回答ありがとうございます。


やはり正確にタイミングを捕えるのは難しそうですね。
カラム幅や表示文字数などを元に、省略するタイミングを独自で判断する方法で検討してみます。


いろいろアドバイスいただき、ありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)