Forums: 公開討議 (Thread #35661)

FirstVisibleLineプロパティの使い方について (2014-06-29 21:24 by yabuhara #73671)

FirstVisibleLineプロパティの使い方について

Azuki-1.7.10をVisual Studio 2013 Express for Windows Desktop のC#
プロジェクトで使用しております。

特定の行の先頭にカーソルを移動し、その行を表示上の1行目にするために、
以下のようにコードを書いてみました。

int p;
(pに有効な論理行番号をセットする処理)
 azuki1.Document.SetCaretIndex(p, 0);
azuki1.View.ScrollToCaret();
azuki1.View.FirstVisibleLine(p);

上記のコードを実行すると、カーソルは期待した位置に移動しますが、対象
行の表示上の位置は変わりません。また画面の描画が崩れて、一部の行が
重複して表示されたり、複数行がまとめて表示されなくなったりします。

FirstVisibleLineの使い方を間違えているのでしょうか。
お手数ですがどなたかご教示のほどをお願い申し上げます。

Reply to #73671×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login

Re: FirstVisibleLineプロパティの使い方について (2014-06-30 09:43 by psk #73675)

こういうのではダメですか?

using System;
using System.Text;
using System.Windows.Forms;
using Sgry.Azuki;
using Sgry.Azuki.WinForms;

namespace test
{
public partial class Form1 : Form
{
AzukiControl azuki;
public Form1()
{
InitializeComponent();

int p = 200;
azuki = new AzukiControl();
azuki.Parent = this;
azuki.Dock = DockStyle.Fill;

System.Text.StringBuilder sb = new System.Text.StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.Append((i + 1).ToString() + "\n");
}
azuki.Document.Text = sb.ToString();
azuki.Document.SetCaretIndex(p, 0);
azuki.View.ScrollToCaret();
azuki.View.FirstVisibleLine = p;
}
}
}
Reply to #73671

Reply to #73675×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login

Re: FirstVisibleLineプロパティの使い方について (2014-06-30 13:25 by yabuhara #73680)

ご返信ありがとうございました。
コードを拝見して、

SetCaretIndex()→ScrollToCaret()→FirstVisibleLine

という使い方で問題ないとわかりました。

そこで任意の行番号位置にFirstVisibleLineをセットする簡単なテストアプリを
作ってみました。

フォームにtextbox、button、labelとAzukiコントロールを配置して、buttonに以下の
処理を書きました。

private void button1_Click(object sender, EventArgs e)
{
int p = 0;

Boolean result = Int32.TryParse(textBox1.Text, out p);

if(result)
{
if (p < azukiControl1.LineCount)
{
azukiControl1.Document.SetCaretIndex(p, 0);

azukiControl1.View.ScrollToCaret();
azukiControl1.View.FirstVisibleLine = p;

label1.Text = "set sucsess";
}else
{
label1.Text = "set failuer";
}
}
else
{
label1.Text = "set failuer";
}

}

(Azukiコントロールには手動で行を追加しています)

このアプリで動作を確認したところ、Azukiに以下の様な動作が見られました。

A. FirstVisibleLine にカーソル位置より前の行番号をセットした場合 :
a. 指定行が表示されているとき: 指定行が表示上の1行目に来るが、2行目以降の表
                        示が更新されない。
あるいは表示全体が更新されない。
スクロールしたり文字入力すると表示が更新される。
b. 指定行が表示されていないとき: 指定行が表示上の1行目に来る。画面も正常に
更新される。

B. FirstVisibleLine にカーソル位置より後の行番号をセットした場合 :
指定行が表示上の1行目に来るが、2行目以降の表示が更新されない。
あるいは表示全体が更新されない。
スクロールしたり文字入力すると表示が更新される。

FirstVisibleLineそのものは正常に動作していますが、その後の画面更新が正常に行え
ていないように見えます。

なおOSはWindows 8.1 Updateです。

以上、よろしくお願い申し上げます。
Reply to #73675

Reply to #73680×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login

Re: FirstVisibleLineプロパティの使い方について (2014-06-30 21:50 by sgry #73684)

yabuharaさん

山本(sgry)です。Azukiをお使いいただきありがとうございます。

To:pskさん。助太刀ありがとうございます。後は私から回答させていただきます。

ご質問の件ですが、yabuharaさんのコードでも内部的なパラメータは正しく更新されています。
しかしAzukiの内部構造的に、FirstVisibleLineプロパティを更新するだけでは
グラフィック再描画が行われません。
そのため、次のように明示的な再描画を指示する必要があります。

// キャレット位置やスクロール位置を格納する内部パラメータを更新
azuki1.Document.SetCaretIndex(p, 0);
azuki1.View.FirstVisibleLine = p;
azuki1.View.SetDesiredColumn(); // キャレットの上下移動時に軸とするX座標をリセット

// グラフィックを再描画
azuki1.Invalidate(); // Azukiの領域全体の再描画指示をOSに通達
azuki1.View.ScrollToCaret(); // グラフィック的なスクロールを実行
azuki1.UpdateCaretGraphic(); // キャレットのグラフィックの再作成を指示

何点か補足しますと:
(1) SetCaretIndexを呼ぶだけですと、上下方向キーでキャレットを動かすと変な位置に
キャレットが飛んでいくことがありますので「キャレットが維持すべきX座標」を
SetDesiredColumn()でリセットしています
(2) (Win32APIの突っ込んだ話になるので詳細割愛しますが)Invalidate()、
ScrollToCaret、UpdateCaretGraphic()の順に呼ぶと再描画時にチラつきが少ないです

お手数おかけしますが、上記のような再描画命令(など)を加え、改めてご確認ください。

なお、やや蛇足ですが画面の一番上の行にキャレットを置くということですので
キャレットのスクロール余裕幅を0にしておいた方が良いかもしれません。
# 標準では1行の余裕を取るので、画面一番上に特定行を表示した後で左右矢印キーを
# 押すとスクロールが発生します。おそらくお気に召さないと勝手に想像した次第です。

Sgry.Azuki.UserPref.AutoScrollMargin = 0;


以上、ご参考になれば幸いです。
Reply to #73680

Reply to #73684×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login

Re: FirstVisibleLineプロパティの使い方について (2014-07-01 01:13 by yabuhara #73685)

山本様
ご返信ありがとうございました。
グラフィック再描画の件、ご説明ありがとうございました。

ご教示いただいたコードを追加し、更に ViewType =WrappedProportional に対応する
ためのコードを追加しました。


//カーソル位置をセット
azukiControl1.Document.SetCaretIndex(p, 0);

//論理行の表示行位置を取得
int c = azukiControl1.Document.GetCharIndexFromLineColumnIndex(p, 1);
int vp = azukiControl1.View.GetLineIndexFromCharIndex(c);

//vpの値の画面確認用
label2.Text = vp.ToString();

//カーソルの移動と表示処理
azukiControl1.View.FirstVisibleLine = vp;
azukiControl1.View.SetDesiredColumn(); // キャレットの上下移動時に軸とするX座標をリセッ
// グラフィックを再描画
azukiControl1.Invalidate(); // Azukiの領域全体の再描画指示をOSに通達
azukiControl1.View.ScrollToCaret(); // グラフィック的なスクロールを実行
azukiControl1.UpdateCaretGraphic(); // キャレットのグラフィックの再作成を指示


上記のコードでおおよそ目的通りの動作をするのですが、なぜか指定した行が表示上の
2行目に移動します(カーソル位置に1行目を指定した場合のみ、1行目に表示されます)。

表示行位置を取得する方法を間違えているのかとも思いましたが、FirstVisibleLineに
セットされている値は正しいように私には思えます。

まだAzukiを使い始めたばかりなので、根本的なところで勘違いをしているのかも知れま
せん。お手数ですが、いま少しご教示をいただけないでしょうか。

よろしくお願い申し上げます。
Reply to #73684

Reply to #73685×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login

Re: FirstVisibleLineプロパティの使い方について (2014-07-01 09:07 by yabuhara #73690)

テストアプリではなく開発中のアプリケーションで試したところ、どの行も問題なく1行目に
表示されました。お騒がせして申し訳ありませんでした。

なおアドバイスいただきましたスクロール余裕幅の件ですが、今のところ該当する動作に
は遭遇していません。なにか別の設定との兼ね合いかも知れません。

ご助力いただきありがとうございました。
今後とも初歩的な質問をしてしまうかも知れませんが、どうかよろしくお願い申し上げます。
Reply to #73684

Reply to #73690×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Login