C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.11753 の関連記事表示

<< 0 >>
■11753  Re[3]: DataGridでの例外回避
□投稿者/ れい -(2007/12/20(Thu) 23:54:20)
    No11736 (シャノン さん) に返信
    > こちらにupしました。
    > http://www.technoledge.info/DGMin.zip
    
    ちょっとずつ思い出してきました。
    
    ・DataGridはCurrencyManagerのイベントを使って自分を更新している。
    ・現在の位置が変わったときCurrencyManagerはCurrentChangedで通知する。
    ・イベントハンドラは呼び出される順序が保証できない。
    
    なので、CurrencyManagerのイベント処理をしてる最中に
    DataGridの関連するプロパティをいじると、おかしくなります。
    イベントハンドラの追加順とかで動かなくなったり。
    私のところではIsSelectedもちゃんと動きませんでした。
    
    CurrentChangedやPositionChangedイベント終了後に呼ばれるイベントがあればいいのですが、
    CurrencyManagerにはありません。
    
    DataGrid自身が出すイベント、CurrentCellChangedを使うのが順当かと思いましたが、
    CurrentCellChangedイベント終了後に行がSelectされるため、IsSelectedが使えません。
    
    ならDataGridにそういったイベントがあるのかと探すと、MouseDownとかKeyDownとかを使うしかない。
    ためしに作ったら一応動いてはいますが、
    本当に全部うまく動くのか確信が持てない所が問題です。
    
    結局、DataGridはSelectedが変わったときにイベントを投げない仕様なので、
    SelectedItemChangedを自分で実装するのは困難であるということになります。
    CurrentCellChangedはきちんと動くので、セル単位で処理せよということでしょう。
    
    イベントドリブンで設計がダメだとこういうことになるんですよね。
    やっぱりDataGridは嫌いだ。
    
    一応、なんとなく動いてるものを書いときます。
    
        class DataGridEx : DataGrid
        {
            private int _selectedindex = -1;
            public event EventHandler SelectedItemChanged;
            protected override void OnMouseDown(MouseEventArgs e)
            {
                base.OnMouseDown(e);
                CheckSelectedIndex();
            }
            protected override void OnMouseMove(MouseEventArgs e)
            {
                base.OnMouseMove(e);
                CheckSelectedIndex();
            }
            protected override void OnKeyDown(KeyEventArgs ke)
            {
                base.OnKeyDown(ke);
                CheckSelectedIndex();
            }
            protected override bool ProcessDialogKey(Keys keyData)
            {
                bool r = base.ProcessDialogKey(keyData);
                CheckSelectedIndex();
                return r;
            }
            protected override bool ProcessKeyPreview(ref Message m)
            {
                bool r = base.ProcessKeyPreview(ref m);
                CheckSelectedIndex();
                return r;
            }
            public object SelectedItem
            {
                get
                {
                    if (_selectedindex < 0) return null;
                    return this.ListManager.List[_selectedindex];
                }
            }
    
            private void CheckSelectedIndex()
            {
                int newindex;
                if (this.ListManager == null) newindex = -1;
                else if (this.ListManager.Count == 0) newindex = -1;
                else if (this.ListManager.Position == -1) newindex = -1;
                else if (!this.IsSelected(this.ListManager.Position)) newindex = -1;
                else newindex = this.ListManager.Position;
                if (_selectedindex == newindex) return;
                _selectedindex = newindex;
                if (SelectedItemChanged != null) SelectedItemChanged(this, EventArgs.Empty);
            }
        }
    
記事No.11551 のレス /過去ログ25より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -