2022年2月27日日曜日

XAMLのお勉強メモ ③


おつかれさまです。ざわです。
 少し前からXAMLで試してみたことをメモっています。
メモ①メモ②(←リンク貼っときます)

動作環境

 ・Windows10

 ・Microsoft Visual Studio Community 2022 Preview 7.0

 ・Xamarin.Forms

今回試してみたこと

 今回は ちょっとデザインに凝ってみようかなと思い、以下を試してみました。

  1. 背景にグラデーションを使用
  2. パスマークアップ構文を使用して図形やアイコンを描画
  3. 円の描画

 出来上がった画面はこちら。


 MainPage.xaml はこのようになりました。
 

 1. 背景にグラデーションを使用

GridにBoxView(*)を配置し、BoxView に LinearGradientBrush(線形グラデーション)を使って色設定しています。 
(* 単色の四角形を描画するために使用されるビュー) 

<BoxView Grid.RowSpan="3">
    <BoxView.Background>
        <LinearGradientBrush>
            <GradientStopCollection>
                <GradientStop Color="LightPink" Offset="0.0"/>
                <GradientStop Color="Beige"  Offset="1.0"/>
            </GradientStopCollection>
        </LinearGradientBrush>
    </BoxView.Background>
</BoxView>

 

 2. パスマークアップ構文を使用して図形やアイコンを描画

画面上部の図形 と 画面下部のアイコンは、PathオブジェクトのDataプロパティに設定して描画しています。
  

■ 図形の部分
<Grid>
    <Path Data="m233.99998,234.8062l332.00003,0l0,111.96579c-161.40468,-114.40217 -140.04514,13.45784 -332.00003,18.42181l0,-130.38759z"
            Aspect="Fill" Fill="LightPink"/>
</Grid>

図形の加工と設定値の取得には、Method Draw Vector Editor を使いました。
Method Draw Vector Editor の使い方は、
 1) 左側のツールパネルから[Shape Tool] →[Flowchart]で図形を選択し、Canvasに配置
 2) 図形をダブルクリックすると編集可能になるので任意の型に加工
  

 3) 加工し終わったら、画面上部のメニューバーで[View]→[Source]を選択
 4) ソースから<path>の"d=~"の ~部分をコピーして、xamlの<Path Data=~>に貼り付ける
 
 
■ アイコンの部分 
<Path Fill="#99524e" Aspect="Uniform"
      Data="M22.375.065C21.037.12,9.179.721,4.92,4.979A10.018,10.018,0,0,0,3.939,17.94L.007,21.879,2.128,24,6.06,20.061a10.019,10.019,0,0,0,12.961-.981c4.342-4.342,4.868-16.134,4.914-17.464L23.991,0ZM16.9,16.958a7,7,0,0,1-8.683.947l8.72-8.719L14.814,7.064,6.1,15.784A7,7,0,0,1,7.042,7.1c2.512-2.513,9.738-3.595,13.8-3.932C20.523,7.206,19.465,14.393,16.9,16.958Z"
      />
 
アイコンはフリー素材をSVGでダウンロードし、(今回使用したサイトは https://www.flaticon.com/) 
ブラウザで開き、右クリックメニューの「ページのソースを表示」を選択。
ページのソースで <path d="~" /> の~部分をコピーして、xamlの<Path Data=~>に貼り付ける。 



 3. 円の描画

 図形とラベルの間がスカスカっと空いていたので<Ellipse>を使って円を入れてみました。(これはイマイチな仕上がり、、?)
<StackLayout Grid.Row="1" HorizontalOptions="Center" Margin="0, -100, 0, 0" Spacing="10" WidthRequest="180">
    <Grid HeightRequest="60" WidthRequest="60" HorizontalOptions="Start">
        <Ellipse Stroke="Beige" StrokeThickness="2" Aspect="Fill"/>
    </Grid>
    <Grid HeightRequest="40" WidthRequest="40" HorizontalOptions="Center">
        <Ellipse Stroke="Beige" StrokeThickness="2" Aspect="Fill"/>
    </Grid>
    <Grid HeightRequest="30" WidthRequest="30" HorizontalOptions="End">
        <Ellipse Stroke="Beige" StrokeThickness="2" Aspect="Fill"/>
    </Grid>
</StackLayout>

 

 今回はyoutubeをいくつか観て学びました。本日書いたもの以外にも試してみたくなるものもあり、徐々に試していってみたいと思います。


2022年2月18日金曜日

Typora(Markdownエディタ)の紹介⑥ ~クラス図を作成する~

 

こんばんは。ひっくです。

今回も、MarkdownエディタのTyporaを取り扱います。

Typora関連記事

→第1回 はこちら Typora(Markdownエディタ)の紹介①

→第2回 はこちら Typora(Markdownエディタ)の紹介② ~画像の保存先を変更する~

→第3回 はこちら Typora(Markdownエディタ)の紹介③ ~数式を編集する~

→第4回 はこちら Typora(Markdownエディタ)の紹介④ ~シーケンス図を作成する~

→第5回 はこちら Typora(Markdownエディタ)の紹介⑤ ~フロー図を作成する~

→第6回 はこちら TyporaVer1.x リリースに伴い有料化(でもベータ版はまだまだ無料利用可能)

 

今回は図式(クラス図)の記載方法を紹介します。

Typora バージョン


今回確認するTyporaバージョンは、「0.11.18(beta)」となります。

 

拡張機能の有効化


第4回(シーケンス図の作成) と同内容となります。既に有効化されている方は読み飛ばしてください。

 

Markdownで図を作成できる設定となっているか確認します。

設定は、「ファイル」→「設定」→「Markdown」→「文法サポート」から変更できます。

 

以下赤枠の設定がチェックONになっていればOKです。

 

クラス図の記法 (mermaid.js)


Typoraでは「mermaid.js」を使用してクラス図を作成することができます。

以下にクラス図を作成する方法を紹介します。

 

  1. バッククォート「`」× 3 を記載した後、続けて「mermaid」と記載します。

     

    【選択後】のカーソル表示部分に、「mermaid」の構文を使用して作図していきます。

    シーケンス図を作成する場合、「classDiagram」とまず記載し、

    続けてクラス図の要素を記載していきます。

    作図内容は、「空のダイアグラム」と表示されている箇所に表示されます。

    • 【入力時】

    • 【選択後】

     

  2. 以下は作図した際の記載例です。

    入力欄には、以下のような記載をしています。

    classDiagram
    class 顧客 {
     	#BigDecimal 顧客ID
     	#String 氏名
     	#String 住所
     	#Integer 年齢
        +登録() bool
     	+削除()
     	+削除(顧客ID)
    }
    
    class 顧客A~顧客~ {
    	-BigDecimal 株主ID
     	-List~BankAccount~ 登録銀行口座
        +登録()
     	+削除()
     	+削除(株主ID)
    }
    
    class BankAccount{
        +String owner
        +BigDecimal balance
        +deposit(amount) bool
        +withdraw(amount) int
    }
    
    顧客 <|-- 顧客A
    
    顧客#BigDecimal 顧客ID#String 氏名#String 住所#Integer 年齢+登録()+削除()+削除(顧客ID)顧客A<顧客>-BigDecimal 株主ID-List<BankAccount> 登録銀行口座+登録()+削除()+削除(株主ID)BankAccount+String owner+BigDecimal balance+deposit(amount) : bool+withdraw(amount) : int

    構文の詳細は mermaid.js公式 クラス図 で確認可能ですが、以下で簡単に紹介します。

    作成順番が逆になっても表示は問題なくされますが、以下手順で作成すると

    分かりやすいのではないかと思います。

     

    クラスを定義する

    「class クラス名 { メンバ変数・メソッドを定義 }」

    {} 内に可視性(先頭の+表示等)や型、変数名・メソッド名・戻り値等の情報を定義します。

    ※メソッドの戻り値は「メソッド名() 半角SP 型」構文で表現可能ですが、

    メソッド名を日本語表記にするとTyporaでは表示されないようでした。

     

    クラス間の関連を定義する

    「classA クラス間関連性 classB」

    ①で定義したクラス間の関連を、関連性の表記に従い定義します。

    UMLの表記と多少違う(継承が△を使用していない等)ところもあるので、

    必要に応じて注記しておきましょう。

    %%(例)
    classDiagram
    classA <|-- classB : 継承
    classC *-- classD : コンポジション
    classE o-- classF : 集約
    classG <-- classH : 関連
    classI -- classJ : リンク(実線)
    classK <.. classL : 依存
    classM <|.. classN : 実現
    classO .. classP : リンク(破線)
    
    classAclassBclassCclassDclassEclassFclassGclassHclassIclassJclassKclassLclassMclassNclassOclassP継承コンポジション集約関連リンク(実線)依存実現リンク(破線)

    ※関連性の表記は以下の通り

    種別 説明
    < | -- 継承
    *-- コンポジション
    o-- 集約
    --> 関連
    -- リンク(実線)
    ..> 依存
    .. | > 実現
    .. リンク(破線)

     

    多重度を設定する

    「classA ”1” クラス間関連性 "*" classB」

    クラスとクラス間関連性の間に、「””」で囲んだ多重度表記を記載します。

    %%(例)
    classDiagram
        Customer "1" --> "*" Ticket
        Student "1" --> "1..*" Course
        Galaxy --> "*" Star : Contains
    
    CustomerTicketStudentCourseGalaxyStar1*11..*Contains*

    ※多重度の表記は以下の通り(必要に応じて任意の数値に変更する)

    種別 説明
    1 1
    0..1 0または1
    1..* 1以上
    * 複数

 

まとめ


Typoraで図式(クラス図)を作図する方法について、今回は紹介しました。

基本的なクラス図も簡単に作成することはできますので、必要に応じて作成してみてはいかがでしょうか。

設計段階の考察で必要なクラス図(簡易的なレベル)を作成する場合が、利用頻度としては一番多いかもしれません。

興味を持った方は是非一度作成してみてください。

 

今回はこのへんで。ではまた!

2022年2月7日月曜日

C# 10.0 レコード型

どうも、もりもりです。

C# 10.0の便利な機能にレコードクラス(C# 9.0ですでに追加はされている)とレコード構造体があるのでメモ。

レコードクラス/レコード構造体

不変なプロパティを持つようなクラスや構造体を簡潔に書けます。 そして参照型でも値型のようにふるまってくれます。

名前と年齢のプロパティを持ったレコード型の宣言は下記のように書くだけ。

// レコードクラス
public record class PersonClass(string Name, int Age);
// レコード構造体
public record struct PersonStruct(string Name, int Age);

レコードクラスはpublic record PersonClassclassを省略して書いてもOK。

// レコードクラス
var person1 = new PersonClass(Name: "Taro", Age: 35);
Console.WriteLine($"person1: {person1}");

var person2 = new PersonClass(Name: "Hanako", Age: 35);
Console.WriteLine($"person2: {person2}");

Console.WriteLine($"person1 = person2 ? {person1 == person2}");

// レコード構造体
var person3 = new PersonStruct(Name: "Taro", Age: 35);
Console.WriteLine($"person3: {person3}");

var person4 = new PersonStruct(Name: "Hanako", Age: 35);
Console.WriteLine($"person4: {person4}");

Console.WriteLine($"person3 = person4 ? {person3 == person4}");

実行結果はこうなります。

> person1: PersonClass { Name = Taro, Age = 35 }
> person2: PersonClass { Name = Hanako, Age = 35 }
> person1 = person2 ? False
> person3: PersonStruct { Name = Taro, Age = 35 }
> person4: PersonStruct { Name = Hanako, Age = 35 }
> person3 = person4 ? False

また、ToString()でプロパティ名と値を表示してくれるのでこれも意外と便利なところ。 わざわざオーバーライドして書かなくて済むので。
このレコード型と同じようなクラスや構造体を自作しようと思うとEquals()やGetHashCode()をオーバーライドして書かないといけません。
さらにそのようなクラスを複数作ろうものなら。。。(って実際に作ることもあったのでマジで助かります!)

レコードクラスとレコード構造体の違い

違いは「クラスと構造体」の違いとほぼ同じだそうです。
構造体には継承はありませんので、EqualityContractプロパティは生成されないようです。
レコードクラスはimmutableですがレコード構造体はmutableなプロパティが生成されます。
immutableなレコード構造体を作りたい場合はreadonly record structとすればOK。

with式

with式を使うと元のインスタンスは書き換えずにクローンして一部のデータを書き換えることが可能です。

// レコードクラス
person2 = person1 with { Name = "Taro" };
Console.WriteLine($"person2: {person2}");

Console.WriteLine($"person1 = person2 ? {person1 == person2}");

// レコード構造体
person4 = person3 with { Name = "Taro" };
Console.WriteLine($"person4: {person4}");

Console.WriteLine($"person3 = person4 ? {person3 == person4}");
> person2: PersonClass { Name = Taro, Age = 35 }
> person1 = person2 ? True
> person4: PersonStruct { Name = Taro, Age = 35 }
> person3 = person4 ? True

データは書き換えずにクローンだけしたい場合はperson2 = person1 with { };とすればOK。

さいごに

今回は一部の機能しか紹介してませんが、他にも結構便利な機能は追加されてます。 .NET 6のLINQに追加されたMaxBy/MinByとかも地味に嬉しいですね。

業務上では新しい言語バージョンを使える環境はあまりないのですが、C#の更新は毎年楽しみにはしてます。 (次のC# 11.0の候補にはヘンなのも挙がってましたが。。。w) いかに簡潔に書けるかってやはり大事だと思うんですよね。書く人も読む人もイイことしかない。 なので開発環境を選べるのであれば常に最新の安定版を使用したいものです。

以上、もりもりでした。