fc2ブログ



Process of Customization using C#

Prev  «  [ 2024/03 ]   1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  » Next
最新コメント
最新記事
カテゴリ
カウンター
全記事表示リンク

全ての記事を表示する

月別アーカイブ
リンク
最新トラックバック

画層スライドショウ2

プログラム的につまづいたのは、transactionの処理。

59行目 ltr = tr.GetObject(oid, OpenMode.ForWrite, false) as LayerTableRecord;

のところで何度もエラーになる。。うーん、動くはずなんだけどなぁ。。


そしてこの記事みてて、思い当たった。


tr.commit()したあと、また、tr使ってるから、エラーになってる?ってこと?


このプログラムの特異なところは、foreachで何度もtransactionを実行していること。

ひとつひとつ画層表示を繰り返して、指定の時間待って、

また、次の画層表示を実施する。

このため、普通のプログラムなら、tr.commit()は1回だけなんだけど、

このスライドショウの場合、tr.commit()がforeachの中に入らなきゃならない。




それで以下のように、トランザクションをネストさせるように修正したら、無事、動作した。

だが、このプログラムでは、終了が上手くできない(汗)。



using System.Collections.Generic;
using System.Linq;
using System.Windows.Threading;

using Teigha.DatabaseServices;
using BAA = Bricscad.ApplicationServices.Application;
using System.Windows;
using System.Windows.Controls;


/// <summary>
/// 画層スライドショウ
/// </summary>
namespace LayerSlideShow
{
    /// <summary>
    /// UserControl1.xaml の相互作用ロジック
    /// </summary>
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }

        private void SlideGo(int val)
        {
            Database db = BAA.DocumentManager.MdiActiveDocument.Database;

            //トランザクション1開始
            using (var tr = db.TransactionManager.StartTransaction())
            {
                if (val == 0) return;

                var lt = tr.GetObject(db.LayerTableId, OpenMode.ForWrite) as LayerTable;

                int num = 0;

                //ltに含まれる画層名をstringで取り出し
                List<string> listLayer = lt.Cast<ObjectId>()
                    .Select(oid =>
                    {
                        return ((LayerTableRecord)tr.GetObject(oid, OpenMode.ForRead, false)).Name;
                    }).ToList();

                LayerTableRecord ltr;

                foreach (var layer in listLayer)
                {
                    LabelGasoName.Content = num.ToString() + " : " + listLayer[num];

                    DoEvents();//LabelGasoName.Contentの更新

                    //トランザクション2開始
                    using (var tr2 = db.TransactionManager.StartTransaction())
                    {
                        foreach (ObjectId oid in lt)
                        {
                            ltr = tr2.GetObject(oid, OpenMode.ForWrite, false) as LayerTableRecord;

                            if (ltr.Name == listLayer[num])
                            {
                                ltr.IsOff = false;//画層表示
                            }
                            else
                            {
                                ltr.IsOff = true;//画層非表示
                            }
                        }

                        num++;

                        ReDraw();

                        tr2.Commit();

                        int speed = 500 * val;

                        //1秒間(1000ミリ秒)停止する
                        System.Threading.Thread.Sleep(speed);
                    }

                }

            }
        }

        

        /// <summary>
        /// 現在メッセージ待ち行列の中にある全てのUIメッセージを処理します
        /// https://gist.github.com/pinzolo/2814091。
        /// </summary>
        private void DoEvents()
        {
            DispatcherFrame frame = new DispatcherFrame();
            var callback = new DispatcherOperationCallback(obj =>
            {
                ((DispatcherFrame)obj).Continue = false;
                return null;
            });
            Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, callback, frame);
            Dispatcher.PushFrame(frame);
        }

        private void ReDraw()
        {
            //' Redraw the drawing
            BAA.UpdateScreen();
            BAA.DocumentManager.MdiActiveDocument.Editor.UpdateScreen();
            //' Regenerate the drawing
            BAA.DocumentManager.MdiActiveDocument.Editor.Regen();

        }

        private void ButtonEnd_Click(object sender, RoutedEventArgs e)
        {
            SlideGo(0);
        }

        /// <summary>
        /// 標準速
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ButtonGo_Click(object sender, RoutedEventArgs e)
        {

            SlideGo(2);

        }

        /// <summary>
        /// 緩速
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ButtonSlow_Click(object sender, RoutedEventArgs e)
        {
            SlideGo(3);
        }

        /// <summary>
        /// 急速
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ButtonFast_Click(object sender, RoutedEventArgs e)
        {
            SlideGo(1);
        }
    }
}




コンパイル環境 Visual studio 2022 Current V17.1.1 + BricsCAD V22.1.04(x64)
関連記事
スポンサーサイト



テーマ : プログラミング
ジャンル : コンピュータ

C

omment

いくつか気が付いたこと。
コードを見ただけなので確認はしていませんが、気が付いたところを列挙します。
・インターバルを用いて何かを表示するというときには、最初に思いつくのはTimerを使うことだと思いますが、試されましたか?
・Transactionのネストをする必要はないと思います。ひとつのTransactionで事足りるはずです。
それにこの動作では tr.Commit()の必要はなく、最後に tr.Abort()(あるいは省略)を使って元に戻すのが普通ではないでしょうか?
・WPFでは System.Windows.Forms.Application.DoEvents() は使えないんですか?
・ReDrawルーチンを自作しておられますが、
BAA.DocumentManager.MdiActiveDocument.Editor.Regen() だけでは何か不都合が出ますか?

以上気が付いたことでした。

Toshi URL | 2022/07/02 00:16 [ 編集 ]

Re: いくつか気が付いたこと。
Toshi様、いつも、ありがとうございます。

よく、このコードを見ただけで、これだけのことが、気になりますねぇ。

私などは、コードを動かしても分からないことだらけです。。



>インターバルを用いて何かを表示するというときには、
>最初に思いつくのはTimerを使うことだと思いますが、試されましたか?

いや、試していません。
何かのサンプルで今回のコードに近い物があったので、流用しました。


>Transactionのネストをする必要はないと思います。ひとつのTransactionで事足りるはずです。
>それにこの動作では tr.Commit()の必要はなく、最後に tr.Abort()(あるいは省略)
>を使って元に戻すのが普通ではないでしょうか?

確認いたします。



>WPFでは System.Windows.Forms.Application.DoEvents() は使えないんですか?

WPFではDoEvents()がありませんでしたので、
これもどこかのサンプルから流用したと思います。


>ReDrawルーチンを自作しておられますが、
>BAA.DocumentManager.MdiActiveDocument.Editor.Regen() だけでは何か不都合が出ますか?

ReDrawルーチンもネットに落ちていた物をそのまま採用しました。
BAA.DocumentManager.MdiActiveDocument.Editor.Regen() だけでいいか、
確認してみます。


後日、また、報告させてください。


hirahira URL | 2022/07/04 11:32 [ 編集 ]


T

rackback

この記事のトラックバックURL

http://hirahirakamen.blog.fc2.com/tb.php/330-d0474c86


プロフィール

hirahira

Author:hirahira
主にC#(F#、VB.net)によるBricsCADのカスタマイズを行います。Visual Studioを使ってのプログラミングは、2014年頃から始めました。それまでは、AutoCad上で動作するAcadRemoconでscriptを作成していました。土木屋ですので、土木関連のツールが多くなると思います。
BricsCADのプログラミングにあたっては、ネット上のAutoCADのプログラムを参考にして、カスタマイズしているので、逆にAutoCADやIJCADの利用者にも参考になれば幸いです。
開発環境 Visual Studio Community 2022 + BricsCAD V23.1.08(x64)

検索フォーム
メールフォーム

名前:
メール:
件名:
本文:

QRコード
QR