vorfee's Tech Blog

Just another tech blog

SDK形式のcsprojを持つWPFプロジェクトでApp.xamlのMainメソッド自動生成を抑制する方法

SDKプロジェクトのWPFアプリケーションでMainメソッド自動生成を防止する。

Microsoftの公式リファレンスに載っている情報なのだが、忘れやすいためメモ。公式リファレンスの記載場所は以下。

Microsoft.NET.Sdk.Desktop の MSBuild プロパティ - .NET | Microsoft Docs

本記事の適用可能対象フレームワーク

.NET 5以降もおそらくWPFである限りは適用可能。

結論

csprojファイルにEnableDefaultApplicationDefinitionを追加する。

<PropertyGroup>
  <EnableDefaultApplicationDefinition>false</EnableDefaultApplicationDefinition>
</PropertyGroup>

上記を追加した後のcsprojファイルは、以下のようになる。

<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net461</TargetFramework>
    <UseWPF>true</UseWPF>
    <EnableDefaultApplicationDefinition>false</EnableDefaultApplicationDefinition>
  </PropertyGroup>

</Project>

WPFのMainメソッド

Mainメソッドの自動生成を抑制したなら、自力でMainメソッドを作成する必要がある。一般にProgram.csというファイルをプロジェクトに追加し、以下の内容を記載する。

(1)最小形

Visual Studioが自動生成するコードと同じ。

namespace WpfApp1
{
    public static class Program
    {
        [System.STAThread]
        public static void Main()
        {
            var app = new App();
            app.InitializeComponent();
            app.Run();
        }
    }
}

(2)スプラッシュスクリーンを表示

スプラッシュスクリーンを表示する場合、プロジェクトにスプラッシュスクリーンを追加し、メインメソッドの先頭でSystem.Windows.SplashScreen.Showを呼ぶ。

<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">

  <!-- 中略 -->

  <ItemGroup>
    <SplashScreen Include="SplashScreen1.png" />
  </ItemGroup>

</Project>
namespace WpfApp1
{
    public static class Program
    {
        [System.STAThread]
        public static void Main()
        {
            var splashScreen = new System.Windows.SplashScreen("SplashScreen1.png");
            splashScreen.Show(autoClose: true);
            var app = new App();
            app.InitializeComponent();
            app.Run();
        }
    }
}

WPFの依存関係プロパティとは?添付プロパティとは?

注意:本記事は独学による個人的な備忘録のため、誤りが含まれる可能性があります。

依存関係プロパティ(DependencyProperty)

DependencyPropertyWPFプロパティシステム を構成する機能の一つである。

添付プロパティ(Attached Property)

添付プロパティWPFプロパティシステムにおける DependencyProperty の形態の一つである。

依存関係プロパティの概要

.NET 共通型システムには Property が定義されている。いわゆるC#の Property のことだが、ここでは区別のため CLR Property と表記する。

DependencyProperty は CLR Property をラッピングし、WPFプロパティシステム で利用される。平たく言うと、DependencyProperty とは WPF が外部拡張性を獲得し、コントロールをうまく制御するために作られた仕組みの一部のことだ。

WPFのコントロールは例外なく DependencyObject を基底クラスに持つ。これはオブジェクトがWPFプロパティシステムに参加したければ、必ず DependencyObject を基底クラスに持たなくてはいけないというルールがあるからだ。

添付プロパティの概要

添付プロパティは WPFプロパティシステムの機能の1つで、WPFのコントロールに備わっていないDependencyPropertyを、あたかも初めから備わっていたかのように振舞わせることができる機能である。

添付プロパティってどんなの?

WPFを使用するうえで意識することはないが、添付プロパティは普段から頻繁に利用している。例えば以下のようなXAMLも添付プロパティを利用している。どれが添付プロパティか分かるだろうか?

<Grid>
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="100"/>
    <ColumnDefinition Width="300"/>
  </Grid.ColumnDefinitions>
  <TextBlock Grid.Column="0" Text="あいうえお"/>
  <TextBlock Grid.Column="1" Text="かきくけこ"/>
</Grid>

Grid.Column="0" の部分が添付プロパティである。しかし、TextBlock の定義を見ても Grid.Column というプロパティは存在しない*1。では次の例はどうだろうか?

<Canvas>
  <Rectangle Canvas.Top="20" Canvas.Left="55" Width="30" Height="100" Fill="Red"/>
</Canvas>

Canvas.Top="20"の部分が添付プロパティである。ところが Rectangle の定義を見ても Canvas.Top というプロパティは見当たらない。

このように、そのコントロール自体にプロパティが存在しないが、添付プロパティを使用することでコントロールに後付けで DependencyProperty を追加し、値を保持することができる。

先の例において、添付プロパティのCanvas.Top が Rectangle に指定されている。Canvas.Top は Canvas がRectangleを描画する際の絶対座標である。つまり、この値を利用するのはCanvasであり、Rectangle自身はこの値を使用しないが、値を保持できている。

添付プロパティが無かったら何がマズい?

勉強の理解を深めるときに逆転の発想をするのは良いことだ。だから、添付プロパティが無かったらどうなるか想像してみることにする。

もし 添付プロパティ がなかったら、Canvasの実装 はどうなるだろうか?

Canvasの機能要件(例)

  • Canvasは、子に複数個のコントロールを持つことができる
  • Canvasは、子のコントロールにLeft, Topの絶対座標を指定して並べることができる

添付プロパティ無しでこれらの要件を満たすためには、Canvasが子に持つことができるすべてのコントロールにTop、Leftプロパティを定義しなければいけないだろう。きっとMicrosoftの.NETチームはICanvasChildみたいな名前のインターフェースを用意して、Canvasに描画可能なコントロールすべてにこれを実装することになる。

では中心の絶対座標を指定して配置できるようなMyCanvasというコントロールを自作したとする。

MyCanvasの機能要件(例)

  • MyCanvasは、子に複数個のコントロールを持つことができる
  • MyCanvasは、子のコントロールにCenterの絶対座標を指定して並べることができる

このコントロールの子はCenterというプロパティが必要で、IMyCanvasChildを実装しなければならない。するとどうだろう、Microsoftの.NETチームはそんなものを知らないので、WPFのすべてのコントロールはIMyCanvasChildを実装していない。なのでWPFのコントロールはMyCanvasで一切利用できない。

これでは拡張性が無さ過ぎて使い物にならないのは明らかである。だから添付プロパティはWPFの柔軟な拡張性に大きく寄与していることがやんわりと理解できる。

添付プロパティの用途は?

そのうち時間ができたら追記予定・・・

*1:そもそも.NETではプロパティ名にピリオドは使用できないことからも、このプロパティが異質であることが見て取れる

Microsoft Wordでページ内リンクをCtrl+ クリックし、リンク先に飛んだ後に元の位置に戻る方法

仕事でWord仕様書を読まされる際、ページ内の参照が多用されていることがあるかもしれない。

この記事はこんな方のためのものです

  • 何かとWordを使う機会がある
  • Ctrl + クリックで別ページに飛んだが、元の位置が分からなくなった
  • ブラウザなら戻るボタンを押せば元の位置に戻るのに・・・イライラ

結論

Alt + 左矢印 を押せば元の位置に戻ります。

でも俺はブラウザみたいに戻るボタンを表示したいんだ!という場合

Google Chromeのようにウインドウの左上に戻る/進むボタンを表示できます。

設定手順(Word2016)

  1. クイックアクセスツールバー(Wordウインドウ枠左上)の ▼ をクリック
  2. 「その他のコマンド」をクリック
  3. コマンドの選択から「リボンにないコマンド」を選択
  4. 一覧の中から「←戻る」「→進む」という項目を選択し、追加する

混乱しないためにも、やり直す、元に戻すはクイックアクセスツールバーから削除しておいたほうがよいでしょう。Ctrl+ZとCtrl+Yで代替できますし、この2つは割と常識です。(Alt+矢印左も常識だろ!とは言わないで・・・)

Windows 10の記憶域の新規作成で 0x00000032 エラーが発生する場合の対処

エラーの状態

[コントロールパネル] > [システムとセキュリティ] > [記憶域] > [新しいプールと記憶域の作成] からドライブを選択し、 [プールの作成] をクリックすると、エラーダイアログ(0x00000032)が表示される場合がある。

f:id:vorfee:20180520002924p:plain

画像引用: https://answers.microsoft.com/en-us/windows/forum/windows_10-files-winpc/storage-spaces-win-10-cant-add-new-drive-error/eca10bd6-5564-45a0-9649-d00619a68fe6

修復

バイスマネージャを開き、ディスクを再認識させることで、エラーを修復できる可能性がある。

以下に修復手順の例を示す。

1. デバイスマネージャを開く

Win + Rでファイル名を指定して実行ダイアログを開き、devmgmt.mscを入力する。

f:id:vorfee:20180520003153p:plain

2. デバイスを無効にする

バイスマネージャの該当するディスクデバイスを右クリックし、デバイスを無効にする。

f:id:vorfee:20180520003838p:plain

3. デバイスを有効にする

2と同じ手順で、無効にしたディスクデバイスを再び有効にする。

参照・引用

zshプロンプトの時間表示をリアルタイムっぽく更新する

シグナルについて少し学んだのでzshでの活用法を考えてみた。

方法

zshタイムアウトを1秒に設定する。タイムアウトごとに送られてくるSIGALRMをトリガーにして、プロンプトを更新する。

export TMOUT=1
function TRAPALRM() {
  zle .reset-prompt
}

結果

時計が秒刻みで更新されるようになった。

f:id:vorfee:20170202182502g:plain

発生する問題

  • プロンプトを更新する際に情報の再計算をする。

    時刻以外に再計算するもの(例:git, svnの情報表示など)がたくさんあると、処理しなければならないものが増えて、むやみにリソースを消費する。ノートパソコンならバッテリを消耗するかもしれない。

  • 補完などで行送りが発生すると表示がおかしくなる。

    1秒ごとに更新されてテキストがグチャグチャになる。

別のアプローチ

常に更新するのではなく、コマンドを実行したときだけ更新することもできる。過去に紹介している。

インターネット上のウェブページをオフライン保存する方法

いつ消えるかわからないウェブページを手元に保存するための方法をメモ。

結論

Google Chromeを使用して MHTML 形式で保存するのが最適である。

MHTMLで保存する方法はこの記事の下のほうにある。

続きを読む

コマンドプロンプトを使ってWindows 10のパーティションをカスタマイズしてクリーンインストールする

概要

続きを読む