Quantcast
Channel: 午後わてんのブログ
Viewing all 420 articles
Browse latest View live

WPFとVB.NET、Bindingしたままコントロールを直接変形、TransformGroupの中のRotateTransform

$
0
0

前回の
WPFとVB.NET、アプリでの編集状態保存、名前を付けて保存、回転角度を指定する2つの方法 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14093723.html
これをPixtack紫陽花2ndに組み込もうとして少し躓いたのでメモ

イメージ 3
期待通りに動いているところ

デザイン画面とXAML
イメージ 1


VBコード
イメージ 2

Imports System.ComponentModel

Class MainWindow
    Private FocusBorder As Border '選択中のBorderを入れておく用

    'Borderをクリックした時
    Private Sub Border_Click(b As Border, e As RoutedEventArgs)
        'StackPanelのDataContextを変更する
        sPanel1.DataContext = b.DataContext
        '選択中のBorderを変更する
        FocusBorder = b
    End Sub

    ''' <summary>
    ''' TransformGroupの中から指定したTransformを返す
    ''' </summary>
    ''' <param name="tGroup">RenderTransformとか指定</param>
    ''' <param name="tType">取得したいTransformの指定、RotateTransformとか</param>
    ''' <returns></returns>
    Private Function GetTransform(tGroup As TransformGroup, tType As Type) As Transform
        For Each c As Transform In tGroup.Children
            If tType = c.GetType Then
                Return c
                Exit For
            End If
        Next
        Return Nothing
    End Function

    'アプリの起動直後
    Private Sub MainWindow_Initialized(sender As Object, e As EventArgs) Handles Me.Initialized

        'Borderを作成してStackPanelに追加表示
        For i As Integer = 0 To 1

            '回転角度、拡大率、傾斜角度を同時に指定するのでTransformGroupを使う
            Dim tg As New TransformGroup
            tg.Children.Add(New RotateTransform)
            tg.Children.Add(New ScaleTransform)
            tg.Children.Add(New SkewTransform)

            'Border作成
            Dim b As New Border
            With b
                .Background = New SolidColorBrush(Colors.Tomato)
                .Width = 50
                .Height = 50
                .Margin = New Thickness(20)
                .RenderTransformOrigin = New Point(0.5, 0.5)
                .RenderTransform = tg 'さっきのTransformGroupを指定
            End With

            'Bindingの設定
            'RenderTransformの中からそれぞれのTransformを取得する
            Dim ro As RotateTransform = GetTransform(tg, GetType(RotateTransform))
            Dim sc As ScaleTransform = GetTransform(tg, GetType(ScaleTransform))
            Dim sk As SkewTransform = GetTransform(tg, GetType(SkewTransform))

            '回転角度
            Dim bind As New Binding("Angle")
            bind.Mode = BindingMode.TwoWay
            BindingOperations.SetBinding(ro, RotateTransform.AngleProperty, bind)
            '拡大率
            bind = New Binding("ScaleX")
            BindingOperations.SetBinding(sc, ScaleTransform.ScaleXProperty, bind)
            '傾斜角度
            bind = New Binding("SkewX")
            BindingOperations.SetBinding(sk, SkewTransform.AngleXProperty, bind)

            'TransformGroupに入っている順番がわかりきっているならTransformの取得は
            'tg.Children.Item(0)とか決め打ちでもいいかも?
            'BindingOperations.SetBinding(tg.Children.Item(0), RotateTransform.AngleProperty, bind)
            'BindingOperations.SetBinding(tg.Children.Item(1), ScaleTransform.ScaleXProperty, bind)
            'BindingOperations.SetBinding(tg.Children.Item(2), SkewTransform.AngleXProperty, bind)

            sPanel1.Children.Add(b) 'BorderをStackPanelに追加表示

            'SaveDataを作成してStackPanelとBorderのDataContextに指定
            Dim sd As New SaveData With {.Angle = 0, .ScaleX = 1, .SkewX = 0}
            sPanel1.DataContext = sd
            b.DataContext = sd
            'Borderをクリックした時
            AddHandler b.MouseLeftButtonDown, AddressOf Border_Click
            '選択中のBorder
            FocusBorder = b

        Next
    End Sub

    Private Sub bt1_Click(sender As Object, e As RoutedEventArgs) Handles bt1.Click
        '選択中のBorderの回転角度を30にする

        'BorderのRenderTransformの中のRotateTransformのAngleを直接変更する場合
        'OK
        'Dim ro As RotateTransform = GetTransform(FocusBorder.RenderTransform, GetType(RotateTransform))
        'ro.Angle = 30

        'BorderのDataContextに入れてあるSaveDataのAngleを変更する場合
        'OK
        Dim sd As SaveData = FocusBorder.DataContext
        sd.Angle = 30


        '以下失敗例
        'BorderのRenderTransformにRotateTransformを指定する?場合
        '無視される
        'FocusBorder.RenderTransform.SetValue(RotateTransform.AngleProperty, 30.0R)

        'BorderのRenderTransformに新しいRotateTransformを上書き
        'バインディングが無効になってしまう
        'FocusBorder.RenderTransform = New RotateTransform(30)

    End Sub
End Class


<Serializable>
Public Class SaveData
    Implements ComponentModel.INotifyPropertyChanged

    <NonSerialized>
    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
    Private Sub OnPropertyChanged(name As String)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
    End Sub

    Private Property _ScaleX As Double
    '拡大率横用
    Public Property ScaleX As Double
        Get
            Return _ScaleX
        End Get
        Set(value As Double)
            _ScaleX = value
            Call OnPropertyChanged("ScaleX")
        End Set
    End Property

    Private Property _SkewX As Double
    '傾斜横用
    Public Property SkewX As Double
        Get
            Return _SkewX
        End Get
        Set(value As Double)
            _SkewX = value
            Call OnPropertyChanged("SkewX")
        End Set
    End Property

    Private Property _Angle As Double
    '回転角度用
    Public Property Angle As Double
        Get
            Return _Angle
        End Get
        Set(value As Double)
            '0から360の間に収めてからSet
            value = value Mod 360
            If value < 0 Then
                value += 360
            End If

            _Angle = value
            Call OnPropertyChanged("Angle")
        End Set
    End Property
End Class



コントロールの変形で使いたいのが3つあって
RotateTransform回転角度、ScaleTransform拡大率、SkewTransform傾斜角度
どれか1つなら前回の方法でよかったみたいだけど、3つ同時だとできなかった

Imageコントロールの回転角度を30に変形する場合

前回の方法
Image.RenderTransform.SetValue(RotateTransform.AngleProperty, 30.0R)


改善した?今回の方法
Dim ro As RotateTransform = GetTransform(FocusBorder.RenderTransform, GetType(RotateTransform))
ro.Angle = 30

    Private Function GetTransform(tGroup As TransformGroup, tType As Type) As Transform
        Dim tg As TransformGroup = tGroup
        For Each c As Transform In tg.Children
            If tType = c.GetType Then
                Return c
                Exit For
            End If
        Next
        Return Nothing
    End Function


コントロールの変形の指定方法

回転角度だけを指定、30度の場合
Image.RenderTransform = New RotateTransform(30)

拡大率縦横だけを指定、縦横2倍の場合
Image.RenderTransform = New ScaleTransform(2, 2)

どれか1つならこんなふうに1行で済むけど、組み合わせるときはTransformGroupを使って
回転角度と拡大率を指定
Dim tg As New TransformGroup
tg.Children.Add(New RotateTransform(30))
tg.Children.Add(New ScaleTransform(2, 2))
Image.RenderTransform = tg

こうなる、ここまでは良かったけど

前回の方法で回転角度を45に変更
Image.RenderTransform.SetValue(RotateTransform.AngleProperty, 45.0R)
これでいいのかと思ったら、これだと無視されて変更されない
どうやらTransformGroupの中にあるRotateTransformまで届いていないみたい
そこでFor Each~NextでTransformGroupの中からRotateTransformを取得して、それに直接指定するようにしたのが今回の方法
まともな方法がありそうだけど見つからなかった

For Each~Nextを使わないで取得する
TransformGroupに入っている順番は入れた時の順番みたいなので、さっきの例だと
tg.Children.Item(0)にRotateTransformに入っていて
tg.Children.Item(1)にScaleTransformが入っている
決め打ちみたいだけどこっちのほうがラクかも

これでなんとかなった
BindingやDataContextは設定が難しいけどあとが楽になる感じ

Pixtack紫陽花2ndの様子
イメージ 4
SliderのValueChangedイベントで変形させていたのを、SliderとImageをBindingするようにしただけだから、見た目も動作も変わっていないw
でもコードも減ったし動きも軽くなったかも?
次は名前を付けて保存機能




Pixtack紫陽花2nd、編集状態をファイルに保存できるようにした

$
0
0

Pixtack紫陽花2nd 1.1.2.4


2016/04/30
編集状態を名前を付けて保存できるようにした

2016/04/28
透明にしたい色をパレットから選択したとき透明にならないのを修正
スライダーと画像の回転角度などの変形の連携の方法を
ValueChangedイベント方式からBindingとDataContextを使った方法に変更した

2016/04/17
jpeg保存の時の品質(画質)を指定できるようにした
上下カーソルキーで画像移動すると階層も移動してしまう不具合修正
スライダーやメニュー項目などをカーソルキーで操作できなかった不具合修正…できたと思ったけど直っていなかった

イメージ 1


編集状態をファイルに保存
イメージ 2
さっきの説明画像とバジルと霧吹きの画像の3つ表示したところ

イメージ 3
画像の位置を変更して回転とかした状態
この状態を保存する

イメージ 4
適当な名前を付けて保存

イメージ 5
表示していた画像を消去してから

イメージ 6
さっき保存したファイルを開いてみる

イメージ 7

イメージ 8
編集状態が再現された!

編集状態が保存されたファイル
イメージ 9
拡張子は独自の.pa2にしてみたけどファイルの形式はZipファイルになっているので、拡張子を.zipに変更すると中を見ることができる
確かエクセルのxlmsファイルも実はZipだったはず、今ではエクセルの気持ちが少しわかる気がするw


イメージ 10
拡張子をZipに変更して中を見たところ
Bitmap.tiffに画像が保存されている、Tiff画像形式には1つのファイルに何枚も画像を入れることができるのを利用している、今回のは3枚入っている
data.xmlにはそれぞれの画像の情報が入っている、表示位置、回転角度、拡大率、傾斜角度がそれ

イメージ 11
解凍してみたところ、画像が見えている


イメージ 12
data.xmlをテキストエディタのMeryで開いたところ

Bitmap.tiffをWindows フォトビューワーで開いてみると
イメージ 13
イメージ 14
イメージ 15
3枚の画像が入っているのが確認できる
Windows フォトビューワーってあんまり使うこと無くて知らなかったけど意外に便利だねえ
ちなみにPixtack紫陽花2ndや無印で複数画像が入っているTiff画像を開いても1枚目の画像しか表示されない


説明画像で使ったフォントは「にゃしぃフォント改二」
参照したところは
DataContractSerializerを使って、オブジェクトのXMLシリアル化、逆シリアル化を行う: .NET Tips: C#, VB.NET
http://dobon.net/vb/dotnet/file/datacontractserializer.html
DataContractSerializerを使って、Object配列やArrayListをXMLシリアル化する: .NET Tips: C#, VB.NET
http://dobon.net/vb/dotnet/file/datacontractserializer2.html
OnSerializedAttribute クラス (System.Runtime.Serialization)
https://msdn.microsoft.com/ja-jp/library/system.runtime.serialization.onserializedattribute(v=vs.110).aspx
DataContractSerializerのデシリアライズで既定値を設定する « 空談録
http://artfulplace.net/blogs/set-default-value-to-datacontract-serialized-object/
ありがとうございます



今回のでやっと編集状態を保存する機能をつけることができた
前回までのテストアプリでも結構難しかったので、本番ではどこまでできるかなあって感じだったけど、なんとかできて満足、無印の時はできなかったからねえ
どうなるかわからないのが保存ファイルの互換性、今後のバージョンアップで保存する項目が増えたり変更になった時にどうなるのか、たぶん互換性はなくなるかなあ

イメージ 16


ダウンロード先
Dropbox

ヤフーボックス



関連記事(新しい順)
WPFとVB.NET、Bindingしたままコントロールを直接変形、TransformGroupの中のRotateTransform ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14098125.html
WPFとVB.NET、アプリでの編集状態保存、名前を付けて保存、回転角度を指定する2つの方法 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14093723.html



ベランダ菜園、イチゴ初収穫、強風で葉っぱ破れる、腐る、トマト(レッドオーレ)の葉っぱに黒い斑点

$
0
0

トマト(レッドオーレ)
A株
イメージ 2
イメージ 26
雑草よりは大きくなるの早いけど、去年よりゆっくり


B株
イメージ 3

イメージ 11
雨風が強かった日の翌日
葉っぱに黒い斑点ができている、4つの株全部
去年も似たようになって、その時はアザミウマにかじられたせいだと思っていたけど
今年はアザミウマは見当たらないから違うみたい?
風雨には晒さないほうがいいのかも
イメージ 27
このB株だけは大きくなっている



販売されているトマトの殆どは一代交配種のようなので、去年のこぼれ種から発芽したC、D株はどうなるかしらねえ
イメージ 5
イメージ 25
あんまり変化ないね



スイートバジル
イメージ 4

イメージ 12
雑草の勢いが止まらないので

イメージ 13
取り除いた
スイートバジルはなかなか大きくならないなあ
4日前と比べてもほとんど変化がない


いちご
イメージ 1

イメージ 6
イメージ 30
今年はいまいちなのは去年放置しすぎたせいもある
これは食べられる状態になりそうにないなあ

イメージ 8
茶色くなって大きくならないものがたくさんある

イメージ 24
プランターに植えてある方も小さい実ばかり

摘蕾、摘果
イメージ 36
50個位は取り除いたかなあ

イチゴ腐る
イメージ 10
イメージ 32
イメージ 33
腐ってしまう実も出てきた
去年と同じような腐り方

今年初収穫
イメージ 28
去年トマトと同じプランターに植えてあった株から

イメージ 29
一個だけ収穫

イメージ 35
表側は赤いけど

イメージ 31
土に直置き状態だった裏側はまだ白っぽかった

イメージ 34
ヘタの周りの部分がひび割れていて見た目が美味しくなさそうw
でも甘味酸味も十分で今まで採れた中でも1番かもってくらい美味しかった
原因で考えられるのは肥料かなあ、と言っても普通の化成肥料
トマトと同じプランターに植えてあったから、トマトに追肥するとイチゴにも肥料が行くことになっていた、トマトが枯れてきた12月辺りから追肥しなくなってからは3月くらいに1回だけほんの少しバラまいたんだったかな
イチゴは肥料の入れ過ぎに弱いって聞いていたら枯れてしまうかもと思ってみていたけど特に影響ない感じだったんだよねえ
って書いていたら肥料あんまり関係ない感じしてきた、トマトとの相性が良いとかかなあ
そういえばこの株だけ去年は実がつかずに葉っぱだけだったかも


強風で葉っぱが破れる
イメージ 16
最大瞬間風速は2日連続で20m/sだったらしい

イメージ 17
大きめの葉っぱは破れたり

イメージ 18
葉っぱ同士が擦れて黒くなっている

イメージ 19
イメージ 20
この時期の葉っぱは柔らかいせいもあるかな
夏以降は硬くなるから台風でもここまでひどくならないのかも


ハエ
イメージ 23
相変わらず寄ってくるのはハエっばっかり
ミツバチどこー


害虫
イメージ 7
アブラムシはまだそれほど増えていない
羽根つきばかり見る

イメージ 9
イメージ 15
去年に続きイチゴゾウムシによる被害かな、姿は見えず
葉っぱに柄の部分を切られて水が葉っぱまで届かなくてしおれている

イメージ 14
ヨコバイ系

イモムシ
イメージ 21
葉っぱに小さな丸い穴が開いている

イメージ 22
イモムシがいた、見つけたのは5匹だったかな




WPFとVB.NET、動的追加時にControlTemplateの中のControlを取得するにはApplyTemplate

$
0
0
Pixtack紫陽花2ndの画像の表示は
XAMLの方でWindow.Resourcesに
Imageコントロールを入れたControlTemplateをThumbコントロールに指定しておいて

VBコードで
  1. Thumb作成
  2. Window.ResourcesからControlTemplateを取得
  3. ThumbにControlTemplateを指定
  4. ControlTemplateの中のImage取得
  5. 画像ファイルからBitmapImage作成
  6. ImageのSourceにBitmapImageを指定
  7. ThumbをCanvasに追加して表示
この流れで表示している
問題は4番のところでたまにImageを取得できないことがあった
今回これを解決できたっぽいので方法

4番の前、つまり中のImageを取得する前にApplyTemplateを実行する
Thumb.ApplyTemplate
これで解決できたっぽい

FrameworkElement.ApplyTemplate メソッド(System.Windows)
https://msdn.microsoft.com/ja-jp/library/system.windows.frameworkelement.applytemplate(v=vs.110).aspx
アプリケーションでこのメソッドを呼び出すと、要素のビジュアル ツリーが完全であることが保証されます。この保証のステップは、コードでツリーの子要素をチェックする場合に必要になることがあります。テンプレートは要素の有効期間の適切な時点で自動的に要素に適用されるため、アプリケーション内の一般的な要素のロジックで ApplyTemplate を呼び出す必要はありません。
なんか適切な時に自動で処理しているから一般的には呼び出す必要ないって言われているw
でも、どうやらこれを実行するとControlTemplateが再構築されるみたいなので取得に失敗することが無くなった





XAMLとデザイン画面
イメージ 2


VBコード
今回で必要なところは48から97行目まで
それ以外はこういうのができたらいいなあのデモ用
イメージ 3


'FrameworkElement.ApplyTemplate メソッド(System.Windows)
'https://msdn.microsoft.com/ja-jp/library/system.windows.frameworkelement.applytemplate(v=vs.110).aspx
'/Knowledge/Programming/WPF/コントロールテンプレート上のボタンのスタイルの動的変更
'http://www.geocities.jp/kandou_quester/Knowledge/Programming/WPF/_change_style_of_button_on_control_template_dinamically.html
'↑参照したところ

Imports System.Windows.Controls.Canvas
Imports System.Windows.Controls.Primitives


Class MainWindow

    'Thumbのドラッグ移動用
    Private Sub tmb_DragDelta(sender As Object, e As DragDeltaEventArgs)
        Dim t As Thumb = DirectCast(sender, Thumb)

        Dim x As Double = e.HorizontalChange
        Dim y As Double = e.VerticalChange
        Dim tx As Double = GetLeft(t)
        Dim ty As Double = GetTop(t)
        x += tx
        y += ty

        SetTop(t, y)
        SetLeft(t, x)
    End Sub

    'Thumbの中に画像追加
    Private Sub AddImage(cc As Canvas, path As List(Of String), p As List(Of Point))
        For i As Integer = 0 To p.Count - 1
            Dim b As New BitmapImage(New Uri(path(i)))
            Dim img As New Image With {
                .Source = b,
                .Stretch = Stretch.None,
                .Width = b.PixelWidth,
                .Height = b.PixelHeight}
            SetLeft(img, p(i).X) : SetTop(img, p(i).Y) '描画位置指定
            cc.Children.Add(img) '追加
        Next
    End Sub


    ''' <summary>
    ''' Templateを指定したThumbを作成してcanvas1に追加、Templateの中のcCanvasを返す
    ''' </summary>
    ''' <param name="p">Thumbの描画位置指定</param>
    ''' <returns>ThumbのTemplateの中のcCanvas</returns>
    Private Function AddThumb(p As Point) As Canvas
        Dim t As New Thumb 'Thumb新規作成
        'ThumbにTemplate設定
        Dim tmp As ControlTemplate = Me.Resources.Item("ct")
        t.Template = tmp 'Resources.Item("ct")

        'ThumbをCanvasに追加、描画位置指定
        SetLeft(t, p.X) : SetTop(t, p.Y)
        canvas1.Children.Add(t)
        'マウスドラッグ移動イベント用
        AddHandler t.DragDelta, AddressOf tmb_DragDelta

        'TemplateのVisualTreeを再構築してからでないと中のCanvasを取得できないので
        t.ApplyTemplate() '再構築!!!
        'そして中のCanvasを取得!!!
        Dim cc As Canvas = t.Template.FindName("cCanvas", t)
        'cc.Background = New SolidColorBrush(Colors.White) '背景白色

        Return cc

    End Function

    'Button1クリック
    'Templateの中のコントロールの取得テスト
    Private Sub bt1_Click(sender As Object, e As RoutedEventArgs) Handles bt1.Click
        Dim t As New Thumb 'Thumb新規作成
        t.Name = "ControlTemplateを適用したThumbです" '目印
        'リソースの中からControlTemplateを取得
        Dim tmp As ControlTemplate = Me.Resources.Item("ct")
        'ThumbにTemplate設定
        t.Template = tmp 'Resources.Item("ct")


        'ここからTemplateの中のコントロールの取得
        Dim emp As Canvas = t.Template.FindName("cCanvas", t)
        '↑ここでは取得できない
        '先にTemplateのVisualTreeを再構築する必要があるので
        t.ApplyTemplate() '再構築!!!
        'そして中のコントロールを取得!!!
        Dim cc As Canvas = t.Template.FindName("cCanvas", t)
        Dim cb As Button = t.Template.FindName("cButton", t)
        Dim cl As ListBox = t.Template.FindName("cListbox", t)

        Dim cctp As Thumb = DirectCast(cc.TemplatedParent, Thumb)
        Dim cbtp As Thumb = DirectCast(cb.TemplatedParent, Thumb)
        Dim cltp As Thumb = DirectCast(cl.TemplatedParent, Thumb)

        Dim cctpn As String = cctp.Name

    End Sub

    'Button2クリック
    'canvas1に画像追加したThumbを追加
    Private Sub bt2_Click(sender As Object, e As RoutedEventArgs) Handles bt2.Click
        Dim t As New Thumb
        SetLeft(t, 0) : SetTop(t, 0)
        canvas1.Children.Add(t)
        t.Template = Resources.Item("ct")
        t.ApplyTemplate() '再構築!!!
        AddHandler t.DragDelta, AddressOf tmb_DragDelta

        Dim cc As Canvas = t.Template.FindName("cCanvas", t)

        Dim path As New List(Of String)({"D:\ブログ用\テスト用画像\collection_1.png",
                                        "D:\ブログ用\テスト用画像\collection_2.png",
                                        "D:\ブログ用\テスト用画像\collection_3.png"})
        Dim p As New List(Of Point)({New Point(10, 10),
                                    New Point(50, 60),
                                    New Point(80, 20)})
        Call AddImage(cc, path, p)
    End Sub

    'Button3クリック
    'canvas1に画像追加したThumbを追加
    Private Sub bt3_Click(sender As Object, e As RoutedEventArgs) Handles bt3.Click
        Dim t As New Thumb
        SetLeft(t, 0) : SetTop(t, 0)
        canvas1.Children.Add(t)
        t.Template = Resources.Item("ct")
        t.ApplyTemplate() '再構築!!!
        AddHandler t.DragDelta, AddressOf tmb_DragDelta

        Dim cc As Canvas = t.Template.FindName("cCanvas", t)

        Dim path As New List(Of String)({"D:\ブログ用\テスト用画像\hueRectT210.png",
                                        "D:\ブログ用\テスト用画像\hueRectT255.png",
                                        "D:\ブログ用\テスト用画像\hueRectT300.png"})
        Dim p As New List(Of Point)({New Point(10, 10),
                                    New Point(30, 30),
                                    New Point(80, 20)})
        Call AddImage(cc, path, p)
    End Sub

End Class



イメージ 6
ControlTemplateの中にはCanvasとButtonとListBoxの3つ入れてみた
それぞれ名前を付けておく、この名前を使って取得することになる

アプリを起動して中のControlを取得して確認してみる
イメージ 4
ボタン1が確認ボタン
押すとコードの方に一時停止が指定してあるので

イメージ 5
赤の中身が青
85行目でApplyTemplateを実行しているので、その前の82行目では中のControlを取得できていないのでNothingになっている
87行目からの3行ではそれぞれ3つのControlが取得できている(cc, cb, cl)
91行目からの3行では取得したControlのTemplateParentを取得していて、すべてThumbになっているのがわかる(cctp, cbtp,cltp)
これで作成したThumbに適用したControlTemplateの中のControlが取得できていることがわかった



ボタン2とボタン3は押すと3つの画像を一つにまとめた画像を表示する
イメージ 1
画像をグループ化してまとめて移動できたらいいなあ

イメージ 7
Thumbの中のCanvasにImageを3つ追加したものを表示

こういう画像や表示場所の決め打ちならできたけど、実際にはグループ化解除や画像の選択方法、その編集状態の保存とか入ってくるから難しいし、その前に今のPixtack紫陽花2ndはThumbの中に直接Imageを入れているから複数画像を入れられないから、ImageをCanvasに変更してそこにImageを追加する方法に書き直さないとできない
グループ化も無印の時にはできなかったからなんとかしたいんだよねえ


今回のコード



ベランダ菜園、トマト苗の成長止まる、イチゴは収穫より廃棄が多い、スイートバジルは普通

$
0
0

イメージ 48
ここ1ヶ月の降水量
一昨年と同じくらいだけど雨の日が多い

いちご
イメージ 1
手前の大きいプランターの株が一番元気な感じなんだけど

イメージ 2
イメージ 3
イメージ 4
腐ってカビが生えるものが3割くらい出てる

イメージ 10
定植できなくてポットに植えっぱなし

イメージ 11
こっちは表面が茶色で腐っているのとは違う感じだけど食べられそうにない

イメージ 20
イメージ 21
見た目がキモい

イメージ 22
廃棄

イメージ 24
イメージ 25
この辺りのも廃棄になりそう

イメージ 26
おっ赤くなっている

イメージ 27
見た目イマイチだけど味は良かった

イメージ 28
いい感じのがある

イメージ 29
日の当たらない裏側はまだ白かった…
でもこのあと雨の予報だったからね

イメージ 39
やっと今日晴れた

イメージ 40
土まみれと表面が削れているのは雨?ナメクジ?

イメージ 41
もう一個の方は食べられそうで
味は薄味だった、雨がいっぱい降った後だから?

イメージ 42
イメージ 45
イメージ 46
ひび割れているのは雨のせいかなあ

イメージ 43
イメージ 44
食べられるものより廃棄になるほうが圧倒的に多い



イチゴゾウムシ?
イメージ 12
葉っぱがしおれている

イメージ 13
切り取ってみた
黒い斑点があちこちにある

イメージ 14
一直線に傷が付いている
見た目の傷は小さいけど

イメージ 15
簡単に折れてしまうくらい深いところまで傷ついている

イメージ 19
このせいで水が行き渡らなくてしおれたり枯れたりしているみたい




トマト(レッドオーレ)A株
イメージ 7
イメージ 33
ほとんど成長していないなあ
勝手に生えてきたバジルのほうが大きくなっている

B株
イメージ 8
イメージ 9
イメージ 34
イメージ 35
こっちはかなり大きくなった

イメージ 36
イメージ 37
葉脈以外の部分が茶色

イメージ 38
葉っぱの裏側


こぼれ種からのC,D株
イメージ 5
イメージ 47
A株同様ほとんど変化なし



スイートバジル
イメージ 6
イメージ 32
雑草との差

イメージ 30
イメージ 31
雑草に埋もれそうになる


センチュウ退治?
イメージ 16
晴れの日が少なくてなかなか温度が上げられなかったけど

イメージ 17
この日は晴れてたのでかなり熱くなっていた
体感では50度くらいかな
湯気が出てたけど写真には写ってないね

イメージ 18
どの程度の温度でセンチュウ退治になるかわからないけど
10日以上放置していたから、もういいやってことで別の土に入れ替えた
マルチングに使う透明のビニールシートを使って
規模を大きくした方がいいかなあ



イメージ 23
こういうの見ると雨でかなりの土が飛び散っているみたいで
雨よけかマルチングしたほうがよさそう


WPFとVB.NET、回転したコントロールをマウスドラッグでグリッドスナップ、SortedListはスゴイヤツ

$
0
0
回転後のコントロールをマウスドラッグ移動するときに
グリッド移動(グリッドスナップ)
グリッドスナップする頂点は四角形の各4頂点すべての中で一番グリッドに近いもの
この条件での処理がなんとかできた感じ
イメージ 1
回転していない四角形の移動は今のPixtack紫陽花2ndや無印とほぼ同じ
今回作ったのは回転させて斜めになっている四角形の動き
少し怪しいwけどだいたい期待通り


イメージ 2
WPFではコントロールを回転させても内部的には回転していなくて
見た目だけが変化するので内部と見た目で差(ズレ)ができる
実際に座標を指定するときには内部のものを使うので
見た目と合わせるにはその差を取得する必要がある


最寄りのグリッド座標を取得する
イメージ 3
左上に注目した場合に一番近いのはBなので

イメージ 4
ここに移動させることができればいい
実際には左上、左下、右上、右下の4頂点の中から探すから
16通りの中で一番近いところになる


デザイン画面とXAML
イメージ 5

VBコード
イメージ 15
関係あるのは赤色のとろこだけ

Imports System.Windows.Controls.Primitives

Class MainWindow
    Private Const grid As Integer = 70 'グリッドの大きさ

    'グリッドをPathで描画
    Private Sub DrawGridLine()
        Dim pFigure As PathFigure
        Dim pGeometry As New PathGeometry
        '横線
        For i As Integer = 0 To 50
            pFigure = New PathFigure
            pFigure.StartPoint = New Point(i * grid, 0)
            pFigure.Segments.Add(New LineSegment(New Point(i * grid, 350), True))
            pGeometry.Figures.Add(pFigure)
        Next
        '縦線
        For i As Integer = 0 To 35
            pFigure = New PathFigure
            pFigure.StartPoint = New Point(0, i * grid)
            pFigure.Segments.Add(New LineSegment(New Point(500, i * grid), True))
            pGeometry.Figures.Add(pFigure)
        Next

        '描画
        Dim mPath As New Path With {.Stroke = Brushes.Blue, .StrokeThickness = 1, .Data = pGeometry}
        canvas1.Children.Add(mPath)
        Panel.SetZIndex(mPath, -1) '背面に移動

    End Sub

    'ドラッグ移動
    Private Sub thumb1_DragDelta(sender As Object, e As DragDeltaEventArgs) Handles thumb1.DragDelta
        Dim p As Point = GetOnCanvas(sender)
        Dim x As Double = p.X + e.HorizontalChange
        Dim y As Double = p.Y + e.VerticalChange

        x = x - (x Mod grid)
        y = y - (y Mod grid)
        Dim t As ExThumb = DirectCast(sender, ExThumb)
        SetOnCanvas(t, x, y)

    End Sub

    '対象を指定座標にセット
    Private Overloads Sub SetOnCanvas(t As ExThumb, x As Double, y As Double)
        Canvas.SetLeft(t, x)
        Canvas.SetTop(t, y)
        t.Locate = New Point(x, y)
    End Sub
    Private Overloads Sub SetOnCanvas(t As ExThumb, p As Point)
        Call SetOnCanvas(t, p.X, p.Y)
    End Sub

    '対象の座標を取得
    Private Function GetOnCanvas(obj As Object) As Point
        Return New Point(Canvas.GetLeft(obj), Canvas.GetTop(obj))
    End Function


    '基本座標と4頂点の差を記録
    Private Sub SetDiffPoint(t As ExThumb)
        Dim gt As GeneralTransform = t.TransformToVisual(canvas1)
        Dim BaseP As Point = New Point(Canvas.GetLeft(t), Canvas.GetTop(t))

        With t
            .Locate = BaseP '基本座標
            .DiffLTop = gt.Transform(New Point(0, 0)) - BaseP '左上頂点座標 - 基本座標
            .DiffRTop = gt.Transform(New Point(t.Width, 0)) - BaseP
            .DiffRDown = gt.Transform(New Point(t.Width, t.Height)) - BaseP
            .DiffLDown = gt.Transform(New Point(0, t.Height)) - BaseP
        End With
    End Sub




    '起動中
    Private Sub MainWindow_Initialized(sender As Object, e As EventArgs) Handles Me.Initialized
        Call DrawGridLine()
    End Sub

    '起動直後
    Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        Call SetDiffPoint(thumb2) '起動中ではExThumbが表示されていないので起動直後
    End Sub



    '左上を最寄りのグリッドに合わせる
    Private Sub btLTop_Click(sender As Object, e As RoutedEventArgs) Handles btLTop.Click
        Call SetFitPoint(thumb2, thumb2.DiffLTop)
    End Sub
    '右上を最寄りのグリッドに合わせる
    Private Sub btRTop_Click(sender As Object, e As RoutedEventArgs) Handles btRTop.Click
        Call SetFitPoint(thumb2, thumb2.DiffRTop)
    End Sub

    '指定した頂点をグリッドに合わせる
    Private Sub SetFitPoint(t As ExThumb, fit As Point)
        '左上の座標が最寄りのグリッドからどれだけ離れているか距離を取得
        '離れているぶんを移動
        Dim fp As Point = t.Locate + fit 'グリッドに合わせたい頂点座標
        Dim x As Double = GetNearGridPoint(fp.X) '最寄りのグリッドx座標
        Dim y As Double = GetNearGridPoint(fp.Y) 'y座標

        Dim nx As Double = x - fp.X '最寄りのグリッド座標 - 今の座標 = 距離
        nx = t.Locate.X + nx '今の座標 + 距離 = グリッドにぴったりになる座標
        Dim ny As Double = y - fp.Y
        ny = t.Locate.Y + ny

        Call SetOnCanvas(t, nx, ny) '座標をセット
        't.Locate = New Point(nx, ny)
    End Sub

    '距離取得
    Private Function GetNearGridPoint(xy As Double) As Double
        Dim m As Double = xy Mod grid
        If m > grid / 2 Then
            Return xy + grid - m
        Else
            Return xy - m
        End If
    End Function

    'ドラッグ移動
    Private Sub thumb2_DragDelta(sender As Object, e As DragDeltaEventArgs) Handles thumb2.DragDelta
        Dim t As ExThumb = DirectCast(sender, ExThumb)
        Dim mp As New Point(e.HorizontalChange, e.VerticalChange) '移動距離
        Dim np As Point = GetNearPoint(t, mp) '最寄りのグリッドまでの距離取得
        np = np + t.Locate + mp '最寄りのグリッド + 今の座標 + 移動距離 = ピッタリの座標
        Call SetOnCanvas(t, np) '座標指定
    End Sub


    '最寄りのグリッドにピッタリの座標になるために移動する分の座標を返す
    Private Function GetNearPoint(t As ExThumb, addPoint As Point) As Point
        '四角形(ExThumb)の座標
        Dim bp As Point = t.Locate + addPoint
        '4頂点の現在の座標
        Dim LT As Point = t.DiffLTop + bp '左上の頂点座標
        Dim RT As Point = t.DiffRTop + bp
        Dim RD As Point = t.DiffRDown + bp
        Dim LD As Point = t.DiffLDown + bp
        '4頂点それぞれの最寄りのグリッド座標
        Dim ltg As Point = GetXYDistance(LT) '左上の頂点に一番近いグリッド座標
        Dim rtg As Point = GetXYDistance(RT)
        Dim rdg As Point = GetXYDistance(RD)
        Dim ldg As Point = GetXYDistance(LD)
        'それぞれのグリッドまでの距離
        Dim ltd As Double = GetDistance(LT, ltg) '左上の頂点からグリッド座標までの距離
        Dim rtd As Double = GetDistance(RT, rtg)
        Dim rdd As Double = GetDistance(RD, rdg)
        Dim ldd As Double = GetDistance(LD, ldg)
        '現在の座標と最寄りのグリッド座標の差
        LT = ltg - LT '左上頂点の最寄りのグリッド - 現在の左上
        RT = rtg - RT
        RD = rdg - RD
        LD = ldg - LD

        '4頂点の中から一番近い
        '一番近い座標を得るためにSortedListに座標の差を入れる
        'SortedListはKeyの順番で自動でソートしてくれる
        '        ジェネリックコレクション その3 SortedListとSortedDictionary (System.Collections.Generic) - Programming/.NET Framework/コレクション - 総武ソフトウェア推進所
        'http://smdn.jp/programming/netfx/collections/2_generic_3_sortedlist_sorteddictionary/#indexed_access

        Dim sl As New SortedList(Of Double, Point)
        sl.Add(ltd, LT)
        sl.Add(rtd, RT)
        sl.Add(rdd, RD)
        sl.Add(ldd, LD)
        Dim neko As Point = sl.Values(0)
        '座標の修正値を返す、
        'この座標と現在の座標を足したものが最寄りのグリッドにピッタリの座標になる
        Return sl.Values(0)
    End Function

    '指定座標から一番近いグリッドの座標を返す
    Private Function GetXYDistance(dp As Point) As Point
        Dim x As Double = GetNearGridPoint(dp.X) '最寄りのグリッドx座標
        Dim y As Double = GetNearGridPoint(dp.Y) 'y座標
        Return New Point(x, y)
    End Function

    '2点間の距離を返す
    Private Function GetDistance(p1 As Point, p2 As Point) As Double
        Dim x As Double = p1.X - p2.X
        Dim y As Double = p1.Y - p2.Y
        Dim rd As Double = Math.Sqrt(x ^ 2 + y ^ 2)
        Return rd
    End Function


    Private Sub bt2_Click(sender As Object, e As RoutedEventArgs) Handles bt2.Click
        Dim neko As ExThumb = thumb2
        Dim p As Point = GetNearPoint(thumb2, New Point(0, 0))
    End Sub


    Private Sub btAutoFit_Click(sender As Object, e As RoutedEventArgs) Handles btAutoFit.Click
        Dim p As Point = GetNearPoint(thumb2, New Point(0, 0))
        Dim np As Point = p + thumb2.Locate
        Call SetOnCanvas(thumb2, np)
        thumb2.Locate = np

    End Sub
End Class


Public Class ExThumb
    Inherits Thumb
    Public Property Locate As Point 'ExThumb自身の座標、基本になる座標
    Public Property DiffLTop As Point 'Locateから左上頂点座標までの差
    Public Property DiffRTop As Point '右上
    Public Property DiffRDown As Point '右下
    Public Property DiffLDown As Point '左下

End Class

'毎回計算するのはめんどいからExThumbに4頂点の座標のプロパティをもたせたほうが良さそう
'4頂点の座標は元の座標からの差を記録したほうが良さそう
'そうすれば4頂点の変更はExThumbの変形時だけに留められる



グリッドの大きさ指定
イメージ 16


ExThumbクラス
イメージ 6
マウスドラッグ移動に適したコントロールのThumbを継承したクラスを作成
名前はExThumbにした
このクラスには値をもたせているだけ
自身の座標のほかは四隅の座標までとの差
例えば自身の座標が(1, 2)の時に左上が(10, 20)だったら
DiffLTopは(10 - 1, 20 - 2) なので (9, 18)を入れておくことになる
この差が変化するのは回転させた時だけで、今回は回転角度は固定なので
アプリの起動直後に値を入れるだけになる
Locateだけは移動した時に書き換える

さっきのプロパティに値を入れる
SetDiffPoint
イメージ 13
TransformToVisualで得られるGeneralTransformのTransformメソッドで元の位置から回転後の座標を取得できる
これをアプリの起動直後に実行するので

Loadedイベントで
イメージ 14


2点間の距離を返す
GetDistance
イメージ 7
中学校で習ったらしいけど全く憶えていなかったのでググってそのまま

指定した位置から一番近いグリッドの位置を返す
GetNearGridPoint
イメージ 10

指定した座標から一番近いグリッドの座標を返す
GetXYDistance
イメージ 9
さっきのGetNearGridPointを使っているけど
ひとつにまとめたほうが良かったかも、よくわからん


↑の3つのGet~を使って
どれくらい移動させればぴったりになるかを返す
GetNearPoint
イメージ 8
引数は移動させるExThumbとマウスで移動した分の距離のPoint
16通りの中から一番近いところと場所を探す
四隅の頂点それぞれの一番近いグリッドとの距離を取得し終わっているのが
148行目
そこからその4つの中でさらに一番近いものとその場所を取得するために
SortedListっていうジェネリックコレクションってのを初めて使ってみた
他のコレクションと同じように値(Value)を入れるんだけど、値と一緒にペアとなる
Keyも入れられてさらにKey順に自動で並べ替えてくれるスゴイヤツ

SortedListにKeyとValueを入れたところ
イメージ 18
23,25,34,36とKeyの順番で並んでいる

この自動並べ替え機能を利用して最小値となる座標を取得している
Keyに距離を入れて、Valueに座標を入れていけばKey順に並べてくれるので
先頭のValueを取り出せば、それが最短距離の座標になる
これが164行目
この最短距離の座標はグリッドまでの差なので、今の座標に足せばピッタリになる
あとはThumbのDragDeltaのイベントの時に呼び出すだけ

ThumbのDragDeltaイベント
イメージ 11
120行目でさっきのGetNearPointで差を取得
それに今の座標とマウスの移動分を足してピッタリの座標が121行目
122行目でCanvasに配置するSetOnCanvasで移動完了

SetOnCanvas
イメージ 12
Canvas.SetLeftとCanvas.SetTopで配置しているだけ


ここまで作ったけどPixtack紫陽花2ndに使うかどうかまだわからない
今はグループ化に挑戦しているけどかなり難しくてもう10日くらい経ったのかな
いろいろ試しているうちにできあがったのが今回のもの
グループ化はできたとしても基礎からの大幅書き直しになるからすんごい時間かかりそう
無印の時と違ってテストを重ねて慎重になっていたはずなんだけど
やっぱりこうなったかあって感じ

グループ化もグリッド移動もエクセルのものを目指して作っているんだけど
今回改めてエクセルのグリッド移動の動きを見ていたら思っていたのとは違って
思っていたのは今回作った動きなんだけど、エクセルの方は回転後の図形を
グリッド移動(Altキー押しながらの移動)しても四隅の頂点とセルのグリッドには合わせて移動していない

エクセルで
回転した四角形を横方向にグリッド移動(Altキー押しながらの移動)した時
イメージ 17
実際の動きは四隅の頂点とグリッドの頂点は合わないみたいで
4辺のどれかに合わせる感じなんだねえ
この動きもいつか作ってみたい

参照したところ
ジェネリックコレクション その3 SortedListとSortedDictionary (System.Collections.Generic) - Programming/.NET Framework/コレクション - 総武ソフトウェア推進所
        http://smdn.jp/programming/netfx/collections/2_generic_3_sortedlist_sorteddictionary/#indexed_access
ありがとうございます



コード全部


ベランダ菜園、トマトの支柱をたてた、アームカバーで紫外線対策(自分の)

$
0
0

イチゴは相変わらず不調
実が腐るゾーンと萎びるゾーン
イメージ 2
萎びる確率は100に近い
腐るのは4割くらい

イメージ 1
イメージ 3
萎びるゾーンでは赤くなってもこんな感じで
食べられるものはこの日まで一個も収穫できていない

腐るゾーン
イメージ 4
赤くなっているのはOKだけどその右側の実は

イメージ 5
がくをめくってみたところが腐っている

イメージ 6
食べられそうにないもの20個くらい

萎びるゾーンより
イメージ 7
降りの後の前回と違ってひび割れてはいないので
ひび割れは雨のせいだったみたいねえ

イメージ 8
中央の4つは腐るゾーンから

イメージ 9
ナメクジも居るみたいで這った跡のキラキラを撮ってみたけど
撮れてないなw

イメージ 10
左のしなびているのは洗うとこまで来たけど食べるのやめたw
この調子だと今年の収穫数は10個前後になりそう

5/14
イメージ 11
萎びるゾーンから2つと

イメージ 14
腐るゾーンの葉っぱのしたに隠れているのを引っ張りだして

イメージ 12
この2つ

イメージ 13
土に接触していた先端は少し傷んでいるような感じだった
でも土に接触していてもなんともないものもあるだよねえ

イメージ 15
合計4つ
右の萎びるゾーンからの2つは本当に食べてしまったんですか
って言われそうだけどマズかった(食べてしまった)
大きいのは、うん、美味しい!


スイートバジル
雑草に埋もれてウォーリーをさがして!状態から

イメージ 16
ポツーン

イメージ 17
イメージ 26
この二日間は晴れて気温も上がったせいか大きくなった


イメージ 18
こぼれ種から4つかたまって生えてきたのは

イメージ 19
1つにした
それにしてもこのトマト苗A株が大きくならないので
化成肥料を少し入れてみた、白いつぶつぶがそれ

トマト(レッドオーレ)B株
イメージ 20
イメージ 21
B株は大きくなっているんだよねえ

イメージ 23
古い葉っぱ

イメージ 22
新しく出てきた葉っぱは変色していない
これは雨が降っていなかったからかなあ

イメージ 24
これは雨上がりの後の5/12
比較的新し目の葉っぱも変色している

こぼれ種からのC,D株
イメージ 25
A株同様成長が止まっている

種まきから1ヶ月半経って去年はどうだったか気になって

去年の種まきから1ヶ月半経った時の様子
種まきした時期が違うのもあるだろうけど
去年のほうが大きい

去年の同じ時期だとちょうど発芽したところだった



今年は紫外線対策、トマトじゃなくて自分への
イメージ 31
アームカバー
おたふく手袋の冷感パワーストレッチ

イメージ 32
型番はJW-619
去年Amazonで購入しておいたもの
ついに使う時が来た

装着して最初の感想は
イメージ 33
おおっ、なんかひんやりする、涼しい!

イメージ 34
一部分だけがメッシュになっている
このれのせいかわかんないけど腕全体が涼しい感じになる
最初は冷感やメッシュとか言っても何も着けていないよりは
蒸れて暑くなるんじゃないの?って思っていたけど
全然違った、つけていたほうが涼しい
今はこういう便利なものがあるんだなあと感心しつつ

トマトの支柱をたてた
イメージ 27
B株のプランターに支柱をたてた
去年は上に伸ばしたけど190センチの支柱でも足りなくなって
そこから途中から横に伸ばしていていたんだけど
今年はもっと低い位置から横に伸ばす予定
A株も成長したらここに定植しようと思っている

イメージ 28

イメージ 29
イメージ 30
見た目はこんなだけど去年のよりガッチリできた


ベランダ菜園、鳥?にいちごを食べられた、アームカバーに興味津々なミツバチがいた

$
0
0

2016年4月、日別降水量
イメージ 2


2016年5月、日別降水量
イメージ 1
降水量は多くないけど雨降りの日が多い

晴れの日が珍しく4日続いてこれから雨の予報のとき
イメージ 3
いい感じに熟したのができていたんだけど

イメージ 4
誰かに先に食べられていたw

イメージ 32
鳥かなあ、小さな鳥はいっぱいいるからなあ

イメージ 5
イメージ 6
これは腐ってしまった

収穫
イメージ 7
葉っぱの下側にあったこれはまだ白いけど
これから雨の予報だったから収穫

イメージ 8
萎びるゾーンのここから2つ

イメージ 9
同じく萎びるゾーンから1個

イメージ 10
合計4つ
萎びるゾーンからの3つは小さいけど見た目は今までのよりかなりまとも
味の方も良かった、前回と同じ株からのものなんだけどなあ
晴れの日が続いたのが良かったのかも

イメージ 11
萎びるゾーンからは廃棄

イメージ 12
腐っているわけじゃなさそうなんだよねえ
赤くなっているのはグミみたいな触感、グニグニしてる

イメージ 13
白いのは堅い

イメージ 14
赤くても乾燥しきったようなのは堅い

イメージ 15
イメージ 17
摘み取らないで放置するとこうなる

イメージ 20
左は廃棄、右は収穫

イメージ 21
先端が少し傷んだような感じになっている
前回までは土に触れていたせいだと思ったけど
今回収穫した場所は

イメージ 22
ここと

イメージ 23
ここで土には触れていない
なので土との接触は関係なさそう
雨よけをしていた去年はこういのう無かったから雨かなあ

中の様子
イメージ 26
イメージ 27
上の白いほうが美味しかった
今までのも中の色が白いのが美味しかった気がする

トマト(レッドオーレ)
イメージ 18
前↑雨降り↓後
イメージ 16
葉っぱに黒い斑点が増えるかと思ったけど
そんなに変化ないなあ

イメージ 19
少し増えたけど雨のせいかはわからない感じ
こっちも肥料入れようかなあ

A株
イメージ 24
化成肥料入れたのが良かったのか成長しだした
バジルも大きくなっている

B株
イメージ 25
こっちも肥料入れようかなあ

C,D株
イメージ 29
A株と同じ感じ

スイートバジル
イメージ 31
前回雑草を取り除いた後にプランターの右半分の土をかき混ぜておいた

イメージ 30
4日後の今日
左側に比べると右側のほうが雑草の生え方が弱い
取り除くのが面倒な小さな雑草は土ごとかき混ぜるのがラク


アームカバー
イメージ 28
前回このアームカバーを試した時は曇りがちな天気だったけど
今日2016年5月18日は快晴なのでどんなものかと
やっぱりつけていると快適で全然ヒリヒリしないし蒸れたりもしない
長袖の服でもヒリヒリは防げるけど暑いし作業しにくいからって
去年までは半袖で腕をさすりながらだったんだよねえ

気になったのがミツバチがまとわりつくw
腕に止まったりはしないけど興味があるかのように5分くらい飛んでいた
UVカット機能を謳っているから何か関係あるのかもと
ググったらミツバチは紫外線が見えるらしくて
虫の目による花の写真
http://mushinomephoto.web.fc2.com/index.html
ここを見ると
花は蜜があるところは紫外線を吸収して雄しべや雌しべは反射というか蛍光反応
しているとか
アームカバーを見つけたミツバチは見た目は花に見えるけど匂いが違うなあ
って混乱していたのかもw



WPFとVB.NET、エクセルのグループ化を真似したいからまずはグループ化のRectを取得

$
0
0

グループ化するときに必要なRectを取得する
グループ化ってのはエクセルの図形とかをグループ化っての、あれをどうしても真似したい

イメージ 1
赤枠が必要なRectで対象になるコントロールがぴったり収まる四角形



デザイン画面とXAML
イメージ 2
DockPanelに
bt1って名前をつけたButtonと
canvas1って名前をつけたCanvasを配置しただけ
StatusBarはあんまり関係ないしDockPanelもあんまり意味ないな

VBコード
イメージ 3

Imports System.Windows.Controls.Primitives


Class MainWindow
    Private thumbList As New List(Of Thumb)
    Private waku As Path '枠


    'Thumbをcanvas1に追加表示
    Private Sub AddThumb(p As Point, s As Size, angle As Double)
        Dim t As New Thumb
        With t
            .Width = s.Width
            .Height = s.Height
            .RenderTransform = New RotateTransform(angle)
        End With
        Call SetLocate(t, p)
        thumbList.Add(t)
        canvas1.Children.Add(t)
        AddHandler t.DragDelta, AddressOf ThumbDragDelta

    End Sub

    'Thumbの座標セット
    Private Sub SetLocate(t As Thumb, p As Point)
        Canvas.SetLeft(t, p.X)
        Canvas.SetTop(t, p.Y)
    End Sub

    'Thumbの座標ゲット
    Private Function GetLocate(t As Thumb) As Point
        Return New Point(Canvas.GetLeft(t), Canvas.GetTop(t))
    End Function

    'Thumbのマウスドラッグイベント用
    Private Sub ThumbDragDelta(sender As Object, e As DragDeltaEventArgs)
        Dim t As Thumb = DirectCast(sender, Thumb)
        Dim np As New Point(e.HorizontalChange, e.VerticalChange)
        np = np + GetLocate(t)
        Call SetLocate(t, np)
    End Sub


    '渡されたThumbがぴったり収まるRectを返す
    Private Function GetRect(t As Thumb) As Rect
        Dim gt As GeneralTransform = t.TransformToVisual(canvas1)
        Dim r As Rect = gt.TransformBounds(
            New Rect(New Point(0, 0), New Size(t.Width, t.Height)))
        Return r
    End Function

    '渡されたThumbすべてがぴったり収まるRectを返す
    'RectのUnionメソッドを使う
    Private Function GetUnionRect(thumbList As List(Of Thumb)) As Rect
        Dim r As New Rect
        Dim ur As New Rect 'すべてのRectがぴったり収まるRect用
        Dim rl As New List(Of Rect) '左上座標取得用
        For Each t As Thumb In thumbList
            r = GetRect(t)
            rl.Add(r)
            ur.Union(r)
        Next
        Dim p As Point = GetLeftTop(rl) '左上座標取得
        ur.Location = ur.Location + p '座標変更
        'サイズ変更
        ur.Size = New Size(ur.Width - p.X, ur.Height - p.Y)
        Return ur

    End Function

    '複数Rectの一番左上取得
    Private Function GetLeftTop(rectList As List(Of Rect)) As Point
        Dim x As Double = rectList(0).X
        Dim y As Double = rectList(0).Y
        For i As Integer = 1 To rectList.Count - 1
            x = Math.Min(x, rectList(i).X)
            y = Math.Min(y, rectList(i).Y)
        Next
        Return New Point(x, y)
    End Function


    '赤枠描画
    Private Sub DrawRectPath(r As Rect)
        '前回の枠があったら消す
        If waku IsNot Nothing Then
            canvas1.Children.Remove(waku)
        End If
        '新しい赤枠描画
        Dim p As New Path With {.Stroke = Brushes.Red, .StrokeThickness = 1}
        Dim g As New RectangleGeometry(r)
        p.Data = g
        canvas1.Children.Add(p)
        waku = p
    End Sub



    'アプリ起動直後、Thumbを表示する
    Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        Call AddThumb(New Point(80, 10), New Size(100, 100), 10)
        Call AddThumb(New Point(180, 50), New Size(50, 100), 30)
        Call AddThumb(New Point(200, 100), New Size(120, 100), 20)
    End Sub


    'グループ化した場合のRect表示
    Private Sub bt1_Click(sender As Object, e As RoutedEventArgs) Handles bt1.Click
        Dim ur As Rect = GetUnionRect(thumbList)
        Call DrawRectPath(ur)
    End Sub

End Class



イメージ 4
1個目のRect

イメージ 5
2個目

イメージ 6
3個め

3つの青枠から全体のRect(水色枠)を取得
イメージ 7
RectのUnionメソッドを使って全体のRectを取得

左上座標取得
イメージ 8
3つの青枠の中で一番上と一番左になる座標を取得、地道にMath.MinをFor Nextで回している

左上座標変更
イメージ 9
左上座標を(0,0)から(62,10)へ変更

イメージ 10
移動した分だけサイズも変更でぴったり収まる枠Rectが取得完了

目印の赤枠表示
イメージ 11
Pathを使って赤枠表示

書いている途中で思ったのが要は左上と右下になる座標がわかればいいんだからUnionメソッドを使わないで
左上座標をMath.Min求めるついでにMath.Maxも使って右下座標も求めたらいいんじゃないかってこと



Canvasを入れたControlTemplateをThumbのTemplateに指定して
Canvasの中にImageを配置
Thumb
┗Canvas
┗Image
こんな感じにしておいて、複数のThumbををグループ化したい
今のPixtack紫陽花2ndは
Thumb
┗Image
になっているからそのままだとグループ化できないっぽい

Thumb
┗Canvas
┣Image
┗Path
とかできるようにしたい

グループ化した時は
Thumb
┗Canvas
┣Thumb
┗Canvas
┣Image
┗Image
┗Thumb
┗Canvas
┣Image
┣Path
┗Image
こんな感じになればいいのかなあ


今回のコード





Visual Studio 2015 Update 2をインストールした時の様子とXAMLのUIデバッグツールの表示の切り替え

$
0
0
1ヶ月くらい前だけどVisual Studio 2015 Update 2をインストールした時の様子

イメージ 1


イメージ 2
すべて選択で12GB必要って言われた

イメージ 3
すべて選択のチェック外したら3GB

イメージ 4
何が必要なのかさっぱりわからないので全部入れる

イメージ 5
ここから長い

イメージ 6
最初のスクリーンショットから3時間弱
途中でご飯食べたり風呂に入ったりで戻ってきたら終わっていたので
もう少し短いかも、2時間くらいかなあ



XAMLのUIデバッグツールの表示の切り替え
イメージ 8
デバッグ実行でアプリのウィンドウを表示すると
見慣れないのが表示されていた
便利だけど邪魔なときもあるので

イメージ 7
デバッグ→オプション→チェック外すで非表示になる

イメージ 9
デバッグ中のアプリに表示されているコントロールの詳しい内容が見れる
プロパティの変更もできる

イメージ 10
レイアウトガイド

イメージ 11
選択

イメージ 12





WPFとVB.NET、ControlTemplateをコードで作成

$
0
0
ControlTemplateをコードで作成

イメージ 1


デザイン画面とXAML
イメージ 2


VBコード
イメージ 3

'ControlTemplateをコードで作成

Imports System.Windows.Controls.Primitives

Class MainWindow

    'Canvasを入れたTemplateを持ったThumbを返す
    Private Function GetThumbWithTemplate() As Thumb
        'Canvasを入れたControlTemplate作成
        Dim ct As New ControlTemplate
        'Canvasを入れる、Canvasの名前はccにした
        ct.VisualTree = New FrameworkElementFactory(GetType(Canvas), "cc")

        'Thumb作成してControlTemplateを指定する
        Dim t As New Thumb
        Call SetLocate(t, 0, 0) '配置する座標指定
        canvas1.Children.Add(t) 'MainWindowのcanvas1にThumbを追加
        t.Template = ct 'ControlTemplateを指定
        'Templateを再構成、これで実際にThumbの中にCanvasが構成される
        t.ApplyTemplate()

        Return t
    End Function


    'Thumbを配置する座標指定
    Private Sub SetLocate(t As Thumb, x As Double, y As Double)
        Canvas.SetLeft(t, x)
        Canvas.SetTop(t, y)
    End Sub


    Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        'Canvasを入れたTemplateを持ったThumbを取得
        Dim t As Thumb = GetThumbWithTemplate()
        'Rectangleを作成してTemplateの中のCanvasに配置
        Dim r As New Rectangle With {.Fill = Brushes.Cyan, .Width = 100, .Height = 100}
        Dim tb As New TextBlock With {.Text = "コードでTemplate"}
        '名前を指定して中のCanvas取得
        Dim c As Canvas = t.Template.FindName("cc", t)
        c.Children.Add(r)
        c.Children.Add(tb)

        'マウスドラッグ移動用
        AddHandler t.DragDelta, AddressOf tt_DragDelta
    End Sub


    'マウスドラッグ移動用
    Private Sub tt_DragDelta(sender As Object, e As DragDeltaEventArgs)
        Dim t As Thumb = DirectCast(sender, Thumb)
        Dim x As Double = e.HorizontalChange + Canvas.GetLeft(t)
        Dim y As Double = e.VerticalChange + Canvas.GetTop(t)
        Call SetLocate(t, x, y)
    End Sub

End Class


WPFとVBでアプリ作る準備その1、マウスドラッグでコントロールの移動 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/13900213.html

WPFとVBでアプリ作る準備その2、ControlTemplateの中のControlを取得する ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/13906217.html?type=folderlist
この辺りからの続きになるかな

Imageコントロールは枠線がないけどマウスドラッグ移動が手間
マウスドラッグ移動がラクなのはThumbコントロールだけど枠線が要らない
思いついたのが
見た目がImageコントロールなThumbコントロールがあればいい
それにはControlTemplateを使えば良さそう
Imageコントロールを入れたControlTemplateを持ったThumbを作ればいい
ってことで今まではググッて見つけた方法でControlTemplateを作っていたのが
イメージ 4
これ、XAMLで書いていく方法
Window.ResourcesにControlTemplateを作っておいて(10から17行目)
これを適用したいコントロールのTemplateプロパティで指定(21行目)する方法
今回はこれをVBコードで同じことができたのでメモ
コードで書くと得するのが動的作成ができることと
XAMLのほうは書かなくていいので
イメージ 5
こうなる
そのかわりVBのコードは増えるけどねw
動的作成ができるのが大きい

ControlTemplateの作成
イメージ 6

Dim ct As New ControlTemplate
ControlTemplateを作って、VisualTreeプロパティに中に入れたいコントロールを指定する
イメージ 7
指定するにはFrameworkElementFactoryってのが必要みたいで
中に入れたいコントロールのタイプと目印用の名前をつければいいみたい
ct.VisualTree = New FrameworkElementFactory(GetType(Canvas), "cc")
Canvasコントロールを「cc」って名前をつけていれたところ
Canvasなら後からいくつでもImageでもButtonでも入れられるから便利
あとはこのControlTemplateを使いたいコントロールのTemplateプロパティに指定するだけ

今回はThumbを作って、そのTemplateプロパティにControlTemplateを指定する
        Dim t As New Thumb
        t.Template = ct 'ControlTemplateを指定
これでできあがりな感じなんだけど動的作成には
↓が必要
        'Templateを再構成、これで実際にThumbの中にCanvasが構成される
        t.ApplyTemplate()
Templateの再構成を実行ておくと中のCanvasを取得できるようになる

中のCanvasを取得してCanvasにいろいろコントロールを追加
イメージ 8

Templateの中のコントロールを取得するには目印用の名前が必要
さっきccって名前を付けておいたのでこれをTemplate.FindNameメソッドで使って
Dim c As Canvas = t.Template.FindName("cc", t)
これで中のCanvasを取得しているけどこれはキャストした方がいいのかな
Dim c As Canvas = DirectCast(t.Template.FindName("cc", t), Canvas)
こう?
Dim c As Canvas = CType(t.Template.FindName("cc", t), Canvas)
こう?
どれでもできるんだけど、さっきの再構成をしていないと取得できなくてNothingになる

中のCanvasが取得できればなんでも好きなのを入れられるのでここではRectangleとtextBlockを入れている


意味ないけどボタンやテキストボックスも入れたところ
イメージ 9
イメージ 10
左の緑線のところが書き加えたところ
コードで書くことができるといろいろ融通がきく


今回のコード全部


2016年5月22日追記
関連記事
WPFとVB.NET、ControlTemplateを使ったThumbを回転表示する時に回転させるのはどれがいいのか ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14157487.html









WPFとVB.NET、ControlTemplateを使ったThumbを回転表示する時に回転させるのはどれがいいのか

$
0
0


ControlTemplateを指定したThumbを回転表示させたものをドラッグ移動したら
動きがおかしくてマウスとは違う方向に動いていく
これは
WPFとVB.NET、Canvasの中に回転表示したコントロールのドラッグ移動で気づいたこと ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/13947862.html
この時に書いたのをすっかり忘れていたからなんだけど
この時とは別の方法でできたのでメモ
その方法は
Thumbを回転させるのではなくてTemplateに指定したCanvasを回転させる
これだけ

試しにThumbのTemplateプロパティに
Canvasを入れたControlTemplateを指定して
そのCanvasの中にRectangleとtextBlockを入れたものを表示
Thumb
┗Canvas
┣Rectangle
┗textBlock
これを
それぞれの方法で60度回転表示させたものをマウスドラッグ移動しているのが
イメージ 1
Thumbを回転表示
Thumbの中のCanvasを回転表示
Thumbの中のRectangleとtextBlockを回転表示

左のThumbを回転表示したものだけ動きがおかしいw
中と右は動きがまともなのでこのどちらかを使うことになりそう
中央のCanvasを回転表示するのがいいかなあ

デザイン画面とXAML
イメージ 2


VBコード
イメージ 3

'ThumbのTemplateを指定した時どれを回転させればドラッグ移動がうまくいくのか
'結果はThumb以外のどれかが良さそう
'Template中のCanvasかCanvasの中に入れたものになるけど
'Canvasがいいかなあってところ

Imports System.Windows.Controls.Primitives

Class MainWindow
    'Thumbの座標セット
    Private Sub SetLocate(obj As Object, p As Point)
        Canvas.SetLeft(obj, p.X)
        Canvas.SetTop(obj, p.Y)
    End Sub

    'Thumbの座標ゲット
    Private Function GetLocate(obf As Object) As Point
        Return New Point(Canvas.GetLeft(obf), Canvas.GetTop(obf))
    End Function

    'Thumbのマウスドラッグイベント用
    Private Sub ThumbDragDelta(sender As Object, e As DragDeltaEventArgs)
        Dim t As Thumb = DirectCast(sender, Thumb)
        Dim np As New Point(e.HorizontalChange, e.VerticalChange)
        np = np + GetLocate(t)
        Call SetLocate(t, np)
    End Sub

    '回転角度と拡大率を指定したTransformGroupを返す
    Private Function GetTransformGroup(angle As Double, scale As Double) As TransformGroup
        Dim tg As New TransformGroup
        tg.Children.Add(New RotateTransform(angle))
        tg.Children.Add(New ScaleTransform(scale, scale))
        Return tg
    End Function


    'Canvasを入れたTemplate付きのThumbを作成
    Private Function GetThumb() As Thumb
        Dim ct As New ControlTemplate
        ct.VisualTree = New FrameworkElementFactory(GetType(Canvas), "cc")

        Dim t As New Thumb
        t.Template = ct
        t.ApplyTemplate() 'Template再構成

        'Dim c As Canvas = t.Template.FindName("cc", t)
        'c.Background = Brushes.Transparent 'これをつけると透明部分でもドラッグ移動できる
        Return t
    End Function

    'Thumbを60度回転させて表示
    Private Sub AddThumbRotateThumb()
        Dim t As Thumb = GetThumb()
        Dim c As Canvas = t.Template.FindName("cc", t)
        Dim r As New Border With {
            .Background = Brushes.Cyan, .Width = 100, .Height = 100}
        Dim tb As New TextBlock With {.Text = "Thumbを60度回転"}
        t.Width = r.Width
        t.Height = r.Height
        c.Children.Add(r)
        c.Children.Add(tb)
        canvas1.Children.Add(t)
        SetLocate(t, New Point(50, 100))
        'Thumbを回転
        t.RenderTransform = GetTransformGroup(60, 1)
        t.RenderTransformOrigin = New Point(0.5, 0.5)
        AddHandler t.DragDelta, AddressOf ThumbDragDelta
    End Sub

    'Thumbの中のCanvasを60度回転させて表示
    Private Sub AddThumbRotateCanvas()
        Dim t As Thumb = GetThumb()
        Dim c As Canvas = t.Template.FindName("cc", t)
        Dim r As New Border With {
            .Background = Brushes.Cyan, .Width = 100, .Height = 100}
        Dim tb As New TextBlock With {
            .Text = "Thumbの中のCanvasを60度回転",
            .TextWrapping = TextWrapping.Wrap,
            .Width = r.Width}
        t.Width = r.Width
        t.Height = r.Height
        c.Children.Add(r)
        c.Children.Add(tb)
        canvas1.Children.Add(t)
        SetLocate(t, New Point(200, 100))
        Dim cc As Canvas = t.Template.FindName("cc", t)
        'Thumbの中のCanvasを回転
        cc.RenderTransform = GetTransformGroup(60, 1)
        cc.RenderTransformOrigin = New Point(0.5, 0.5)
        AddHandler t.DragDelta, AddressOf ThumbDragDelta
    End Sub

    'Thumbの中のCanvasの中のRectとtextBlockを60度回転させて表示
    Private Sub AddThumbRotateRect()
        Dim t As Thumb = GetThumb()
        Dim c As Canvas = t.Template.FindName("cc", t)
        Dim r As New Border With {
            .Background = Brushes.Cyan, .Width = 100, .Height = 100}
        Dim tb As New TextBlock With {
            .Text = "Thumbの中のCanvasの中のRectとtextBlockを60度回転",
            .TextWrapping = TextWrapping.Wrap,
            .Width = r.Width}
        t.Width = r.Width
        t.Height = r.Height
        c.Children.Add(r)
        c.Children.Add(tb)
        canvas1.Children.Add(t)
        SetLocate(t, New Point(350, 100))
        'Thumbの中のCanvasの中のRectとtextBlockを回転
        r.RenderTransform = GetTransformGroup(60, 1)
        r.RenderTransformOrigin = New Point(0.5, 0.5)
        tb.RenderTransform = GetTransformGroup(60, 1)
        tb.RenderTransformOrigin = New Point(0.5, 0.5)
        AddHandler t.DragDelta, AddressOf ThumbDragDelta
    End Sub

    Private Sub MainWindow_ContentRendered(sender As Object, e As EventArgs) Handles Me.ContentRendered
        'MsgBox("contentrendered!")
    End Sub


    Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        Call AddThumbRotateThumb()
        Call AddThumbRotateCanvas()
        Call AddThumbRotateRect()

    End Sub
End Class


中の様子を見てみる
イメージ 4
この前の
Visual Studio 2015 Update 2をインストールした時の様子とXAMLのUIデバッグツールの表示の切り替え ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14151544.html
XAMLのUIデバッグツールってのを使って表示されているコントロールの大きさを
見ているところ、この機能面白いねえ


今回のコード



WPFとVB.NET、エクセルのグループ化とグループ化解除を真似したい2

$
0
0

グループ化続き
イメージ 1
ここまではできた

デザイン画面とXAML
イメージ 2

VBコード
イメージ 3
赤いところは意味ない

Imports System.Windows.Controls.Primitives

Class MainWindow
    Private thumbList As New List(Of Thumb)
    Private thumbGroup As Thumb 'Thumbをそのままグループ化したもの用
    Private thumbGroup2 As Thumb 'Thumbの中のImageを取り出してグループ化したもの用

    'Thumbの座標セット
    Private Sub SetLocate(obj As FrameworkElement, p As Point)
        Canvas.SetLeft(obj, p.X)
        Canvas.SetTop(obj, p.Y)
    End Sub

    'Thumbの座標ゲット
    Private Function GetLocate(obf As FrameworkElement) As Point
        Return New Point(Canvas.GetLeft(obf), Canvas.GetTop(obf))
    End Function

    'Thumbのマウスドラッグイベント用
    Private Sub ThumbDragDelta(sender As Object, e As DragDeltaEventArgs)
        Dim t As Thumb = DirectCast(sender, Thumb)
        Dim np As New Point(e.HorizontalChange, e.VerticalChange)
        np = np + GetLocate(t)
        Call SetLocate(t, np)
    End Sub


    'Canvasを入れたTemplate付きのThumbを作成
    Private Function GetThumb() As Thumb
        Dim ct As New ControlTemplate
        ct.VisualTree = New FrameworkElementFactory(GetType(Canvas), "cc")

        Dim t As New Thumb
        t.Template = ct
        t.ApplyTemplate() 'Template再構成

        'Dim c As Canvas = t.Template.FindName("cc", t)
        'c.Background = Brushes.Transparent 'これをつけると透明部分でもドラッグ移動できる

        Return t

    End Function

    'ファイルパスから取得した画像をSourceにしたImageを返す
    Private Function GetImage(uri As String) As Image
        Dim b As New BitmapImage(New Uri(uri))
        Dim img As New Image
        With img
            .Width = b.PixelWidth
            .Height = b.PixelHeight
            .Source = b
        End With
        Return img
    End Function

    '回転角度と拡大率を指定したTransformGroupを返す
    Private Function GetTransformGroup(angle As Double, scale As Double) As TransformGroup
        Dim tg As New TransformGroup
        tg.Children.Add(New RotateTransform(angle))
        tg.Children.Add(New ScaleTransform(scale, scale))
        Return tg
    End Function

    'Thumbをcanvas1に追加表示
    Private Sub AddThumb(p As Point, tg As TransformGroup, img As Image)

        Dim b As BitmapSource = img.Source
        'Thumb作成
        Dim t As Thumb = GetThumb()
        With t
            .Width = b.PixelWidth
            .Height = b.PixelHeight
            'Thumbを回転させるのはドラッグ移動で動きがおかしくなるので中止
            'かわりに中のCanvasを回転させるのでこれは中止
            '.RenderTransform = tg 
        End With
        Call SetLocate(t, p)
        thumbList.Add(t)
        canvas1.Children.Add(t)
        AddHandler t.DragDelta, AddressOf ThumbDragDelta

        'Thumbの中のCanvasを回転させる
        Dim c As Canvas = t.Template.FindName("cc", t)
        With c
            .Width = b.PixelWidth
            .Height = b.PixelHeight
            .RenderTransform = tg '回転拡大表示
            .RenderTransformOrigin = New Point(0.5, 0.5)
        End With
        c.Children.Add(img)

    End Sub


    '渡されたコントロール(エレメント?)がぴったり収まるRectを返す
    Private Function GetRect(e As FrameworkElement) As Rect
        Dim gt As GeneralTransform = e.TransformToVisual(canvas1)
        Dim r As Rect = gt.TransformBounds(
            New Rect(New Point(0, 0), New Size(e.Width, e.Height)))
        Return r
    End Function

    ''渡されたThumbすべてがぴったり収まるRectを返す
    ''RectのUnionメソッドを使う
    'Private Function GetUnionRect(thumbList As List(Of Thumb)) As Rect
    '    Dim r As New Rect
    '    Dim ur As New Rect 'すべてのRectがぴったり収まるRect用
    '    Dim rl As New List(Of Rect) '左上座標取得用
    '    For Each t As Thumb In thumbList
    '        r = GetRect(t)
    '        rl.Add(r)
    '        ur.Union(r)
    '    Next
    '    Dim p As Point = GetLeftTop(rl) '左上座標取得
    '    ur.Location = ur.Location + p '座標変更
    '    'サイズ変更
    '    ur.Size = New Size(ur.Width - p.X, ur.Height - p.Y)
    '    Return ur

    'End Function
    ''複数Rectの一番左上取得
    'Private Function GetLeftTop(rectList As List(Of Rect)) As Point
    '    Dim x As Double = rectList(0).X
    '    Dim y As Double = rectList(0).Y
    '    For i As Integer = 1 To rectList.Count - 1
    '        x = Math.Min(x, rectList(i).X)
    '        y = Math.Min(y, rectList(i).Y)
    '    Next
    '    Return New Point(x, y)
    'End Function


    'グループ化のRectを返す
    Private Function GetGroupRect(rl As List(Of Rect)) As Rect
        '左上と右下の座標を探す
        Dim minX As Double = rl(0).X
        Dim minY As Double = rl(0).Y
        Dim maxX As Double = minX + rl(0).Width
        Dim maxY As Double = minY + rl(0).Height
        Dim r As Rect
        For i As Integer = 1 To rl.Count - 1
            r = rl(i)
            minX = Math.Min(minX, r.X)
            minY = Math.Min(minY, r.Y)
            maxX = Math.Max(maxX, r.X + r.Width)
            maxY = Math.Max(maxY, r.Y + r.Height)
        Next
        '座標からRect作成
        r = New Rect(minX, minY, maxX - minX, maxY - minY)
        Return r

    End Function


    'グループ化パターン1、Thumbの中にThumbのままグループ化
    Private Sub AddGroup(tList As List(Of Thumb))
        Dim rl As New List(Of Rect)
        'canvas1から削除、ドラッグ移動のイベントも解除
        Dim cc As Canvas
        For Each tt As Thumb In tList
            cc = tt.Template.FindName("cc", tt)
            rl.Add(GetRect(cc))
            canvas1.Children.Remove(tt)
            RemoveHandler tt.DragDelta, AddressOf ThumbDragDelta
        Next
        'グループ化した時用のRect取得して新規作成Thumbに指定
        Dim r As Rect = GetGroupRect(rl)
        Dim t As Thumb = GetThumb()
        With t
            .Width = r.Width
            .Height = r.Height
        End With
        Call SetLocate(t, r.Location)
        '新規作成Thumbをcanvas1に追加
        canvas1.Children.Add(t)
        AddHandler t.DragDelta, AddressOf ThumbDragDelta
        thumbGroup = t

        'Thumbの中のCanvasに各Thumbを追加
        Dim c As Canvas = t.Template.FindName("cc", t)
        c.Background = Brushes.LightCyan
        For Each ttc As Thumb In tList
            c.Children.Add(ttc)
            SetLocate(ttc, GetLocate(ttc) - r.Location)
        Next
    End Sub

    'グループ化解除
    Private Sub UnGroup(g As Thumb)
        canvas1.Children.Remove(g)
        thumbGroup = Nothing

        'Thumbの中のThumbを取り出して再配置
        Dim c As Canvas = g.Template.FindName("cc", g)
        For Each t As Thumb In thumbList
            c.Children.Remove(t)
            canvas1.Children.Add(t)
            AddHandler t.DragDelta, AddressOf ThumbDragDelta
            SetLocate(t, GetLocate(t) + GetLocate(g))
        Next
    End Sub


    'グループ化パターン2、中のImageを取り出してグループ化
    '(これは失敗?めんどくさい)
    Private Sub AddGroup2(tList As List(Of Thumb))

        'canvas1から削除、ドラッグ移動のイベントも解除
        Dim rl As New List(Of Rect)
        For Each t As Thumb In tList
            rl.Add(GetRect(t))
            canvas1.Children.Remove(t)
            RemoveHandler t.DragDelta, AddressOf ThumbDragDelta
        Next
        'グループ化した時用のRect取得して新規作成Thumbに指定
        Dim r As Rect = GetGroupRect(rl)
        Dim nt As Thumb = GetThumb()
        With nt
            .Width = r.Width
            .Height = r.Height
        End With
        Call SetLocate(nt, r.Location)
        '新規作成Thumbをcanvas1に追加
        canvas1.Children.Add(nt)
        AddHandler nt.DragDelta, AddressOf ThumbDragDelta
        thumbGroup2 = nt

        'Thumbから取り出したImageを新規作成ThumbのCanvasに追加
        Dim c As Canvas = nt.Template.FindName("cc", nt)
        c.Background = Brushes.Honeydew
        Dim ic As Canvas
        Dim img As Image
        Dim p As Point
        For Each tt As Thumb In tList
            ic = tt.Template.FindName("cc", tt)
            img = ic.Children.Item(0)
            img.RenderTransform = tt.RenderTransform
            ic.Children.Remove(img)
            p = GetLocate(tt)
            c.Children.Add(img)
            SetLocate(img, p - r.Location)
        Next
    End Sub

    'グループ化解除2、失敗
    Private Sub UnGroup2(g As Thumb)
        Dim gp As Point = GetLocate(g)
        canvas1.Children.Remove(g)
        thumbGroup2 = Nothing

        Dim c As Canvas = g.Template.FindName("cc", g)
        Dim imgList As New List(Of Image)
        For i As Integer = 0 To c.Children.Count - 1
            imgList.Add(c.Children.Item(i))
        Next

        Dim p As Point
        Dim img As Image
        For i As Integer = 0 To imgList.Count - 1

            img = imgList(i)
            p = GetLocate(img)
            c.Children.Remove(img)
            AddThumb(p, New TransformGroup, imgList(i))
            'AddThumb(p, img.RenderTransform, imgList(i))
        Next

    End Sub


    'アプリ起動直後、Thumbを表示
    Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        Call AddThumb(New Point(70, 60),
                      GetTransformGroup(20.0R, 1.5R),
                      GetImage("D:\ブログ用\テスト用画像\hueRect000.png"))
        Call AddThumb(New Point(170, 50),
                      GetTransformGroup(355.0R, 1.0R),
                      GetImage("D:\ブログ用\テスト用画像\hueRect030.png"))
        Call AddThumb(New Point(150, 120),
                      GetTransformGroup(45.0R, 1.0R),
                      GetImage("D:\ブログ用\テスト用画像\hueRect060.png"))

    End Sub


    Private Sub bt1_Click(sender As Object, e As RoutedEventArgs) Handles bt1.Click

    End Sub

    'グループ化1
    Private Sub bt2_Click(sender As Object, e As RoutedEventArgs) Handles bt2.Click
        If thumbGroup IsNot Nothing Then Return
        Call AddGroup(thumbList)

    End Sub

    'グループ化1解除
    Private Sub bt3_Click(sender As Object, e As RoutedEventArgs) Handles bt3.Click
        If thumbGroup Is Nothing Then Return
        Call UnGroup(thumbGroup)
    End Sub

    'グループ化2(失敗)
    Private Sub bt4_Click(sender As Object, e As RoutedEventArgs) Handles bt4.Click
        If thumbGroup2 IsNot Nothing Then Return
        Call AddGroup2(thumbList)
    End Sub

    'グループ化2解除(失敗)
    Private Sub bt5_Click(sender As Object, e As RoutedEventArgs) Handles bt5.Click
        If thumbGroup2 Is Nothing Then Return
        Call UnGroup2(thumbGroup2)
    End Sub
End Class




イメージ 4

Thumb
┗Canvas
┗Image
↑これ3つをグループ化して
↓こうした
Thumb
┗Canvas
┣Thumb
┗Canvas
┗Image
┣Thumb
┗Canvas
┗Image
┗Thumb
┗Canvas
┗Image
これは
Thumb
┗Canvas
┣Image
┣Image
┗Image
こうしたほうがすっきりするけどグループ化解除の時にそれぞれのThumbを作成する必要があってめんどくさい
それを試して途中で諦めたのがグループ化解除2ってなっている赤い部分のコード


WPFとVB.NET、ControlTemplateを使ったThumbを回転表示する時に回転させるのはどれがいいのか ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14157487.html
これからThumbのTemplateの中のCanvasを回転させるようにしたのと同時に拡大表示もしている
イメージ 5
Thumb自体は元の大きさで回転もしていない

イメージ 6
中のCanvasを回転拡大表示している


ここまではできた、ここまではいいんだけど次
グループ化したものを拡大や回転させた後にグループ化解除したときに
拡大や回転を引き継ぐのが難しい

回転表示するときの回転軸は画像の中心にしているんだけど
グループ化した後の回転軸はグループ化全体の中心になるから
イメージ 7
グループ化後の回転軸は個別の画像の中心とはズレることになるので
回転した後にグループ化解除した時もこの表示を維持するのが難しい

イメージ 8
左が期待するグループ化解除
右は回転角度だけ引き継いだだけなので回転角度は同じだけど表示位置がずれている
このズレの分の距離がわかればいいんだけどねえ

回転軸の位置は指定できる
RenderTransformOriginプロパティにPoint(0.5, 0.5)
これで中心が回転軸になる
RenderTransformOriginプロパティにPoint(0.0, 0.0)
これだと左上が回転軸になる
なので
    '新しい座標の求め方
    'グループ化前のThumbとCanvasの左上座標の差を持たせておく(差A)
    'グループ化後のCanvasの中心点を求める
    'その中心点は自身の左上座標からどの位置にあるのか求める
    'この数値は自身の(表示?)サイズに対する指数?
    'これを自身のCanvasのRenderTransformOriginに指定する
    '実際に回転表示してThumbとCanvasの左上座標の差を求める(差B)
    '差B - 差A = 差C
    '差C + 自身の座標 = 新しい座標
ってのを思いついたけどめんどくさいというか難しい、迂遠っていうのかしら
もっと楽な方法がありそう

今回のコード


関連記事、古い順
WPFとVB.NET、エクセルのグループ化を真似したいからまずはグループ化のRectを取得 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14151447.html

WPFとVB.NET、ControlTemplateをコードで作成 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14156250.html

WPFとVB.NET、ControlTemplateを使ったThumbを回転表示する時に回転させるのはどれがいいのか ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14157487.html



ベランダ菜園、今年のトマトは無理かも

$
0
0

イメージ 1
腐るゾーンのプランターの外側と内側から2つ

イメージ 2
外側のは先端がしなびていた

イメージ 3
イメージ 4
萎びるゾーンから食べられそうなものが1つ

イメージ 7
イメージ 8
これは食べられないなあ

イメージ 9
ひっくり返したら腐っていた
萎びるゾーンから腐ったものが出たのは初めて

イメージ 10
しなびている

イメージ 11
左は廃棄

イメージ 16
腐るゾーンから

イメージ 17
イメージ 18
やっぱり腐るのね
3割くらい腐る
場所はだいたい決まってガクの下側

イメージ 19
しなび

イメージ 20
萎びるゾーン、ここから1つ
左の2つも珍しくしなびていない

イメージ 21
この日の結果
右上の1個以外は廃棄

イメージ 22
穴が開いているのはアリかなあ
たくさん見かける

イメージ 23
ドライストロベリー

イメージ 26
イメージ 27
まとも

イメージ 41
イメージ 42
これもOK
腐る腐らないの基準がわからん
雨にあたる土に触れる腐ったのが隣りにある
どれも違う感じ

スイートバジル
イメージ 5
4日後
イメージ 33
イメージ 34
保水のためにマルチしたほうが良さそう


トマト(レッドオーレ)A株
イメージ 6
4日後
イメージ 35
化成肥料入れてからは大きくなっている
種まきしたこの土にはよっぽど栄養がなかったんだなあ


イメージ 12
B株、ほんの少し化成肥料を入れた

イメージ 13
白い粒がそれ、20粒位かな

イメージ 36
B株も葉っぱの色が濃くなった気がする

イメージ 37
そろそろ花芽が出てきても良さそうなんだけど見えないなあ

コナジラミの幼虫?
イメージ 38
小さくてよくわからない

イメージ 39
拡大

イメージ 40
もしコナジラミだったら今年のトマトは無理だなあ

イメージ 31
イメージ 32
こぼれ種からのC,D株

センチュウ退治続き
イメージ 14
この前の小さなビニール袋でもできた感じだったので、今度はマルチング用の透明ビニールシートを使って残りの土を全部

イメージ 15
この日は曇だったので作業しやすかった


イメージ 24
この日は晴れ

イメージ 25
触ってみたら熱い、60度あるかなあ

イメージ 28
昨日の時点でかなり熱くなっていたのでもういいだろうと
元のプランターに戻すことにした

イメージ 29
戻した
すのこの下側にあった土も上に移動した形になったせいもあるけど
体積が増した

イメージ 30
左の青い鉢の土も元はこの長方形のプランターに入っていた
ここにランナーで伸びてきたイチゴを植えようかなあ



WPFとVB.NET、TransformGroupのChildrenにAddする順番で結果が変わる

$
0
0
TransformGroupのChildrenにAddする順番で結果が変わる

RenderTransformをデザイン画面で指定しているときは自動で適当な順番になるから気にしていなかった、というか順番で結果が変わるとは思っていなかった
なのでコードで書くときにも順番を気にしないで書いていたら期待した形と違ったものが表示されておかしいなあ、ってなかなか気づけなかったのでメモ


イメージ 1
同じ値を指定しても順番を帰ると結果も変わる
元の形は正方形、これを変形
指定している値は同じで回転角度30、横拡大率0.5、縦拡大率1.2

プロパティの変換の項目で指定した時の順番は自動で
Scale→Skew→Rotate→Translateになる
拡大→傾斜→回転→位置
これの順番を入れ替えてRotateを先頭にすると
左のようなひし形になる


VBコードでBorderに
回転角度30、横拡大率0.5、縦拡大率1.2する場合は
Dim tg As New TransformGroup
tg.Children.Add(New ScaleTransform(0.5, 1.2))
tg.Children.Add(New RotateTransform(30))
Dim b As New Border
b.RenderTransform = tg
こんな感じでOK
TransformGroupのChildrenにAddする順番が大切



ここからは蛇足
イメージ 2
TransformGroupのChildrenの順番
RotateTransform→ScaleTransform
ScaleTransform→RotateTransform


デザイン画面とXAML
イメージ 3


VBコード
イメージ 4

Class MainWindow
    Private mihonRotateScale As Border
    Private mihonScaleRotate As Border


    ''' <summary>
    ''' TransformGroupの中から指定したTransformを返す
    ''' </summary>
    ''' <param name="tGroup">RenderTransformとか指定</param>
    ''' <param name="tType">取得したいTransformの指定、RotateTransformとか</param>
    ''' <returns></returns>
    Private Function GetTransform(tGroup As TransformGroup, tType As Type) As Transform
        For Each c As Transform In tGroup.Children
            If tType = c.GetType Then
                Return c
                Exit For
            End If
        Next
        Return Nothing
    End Function


    Private Function ResetScaleRotate() As TransformGroup
        Dim tg As New TransformGroup
        tg.Children.Add(New ScaleTransform(1, 1))
        tg.Children.Add(New RotateTransform(0))
        Return tg
    End Function

    Private Function ResetRotateScale() As TransformGroup
        Dim tg As New TransformGroup
        tg.Children.Add(New RotateTransform(0))
        tg.Children.Add(New ScaleTransform(1, 1))
        Return tg
    End Function


    Private Function GetBorder(tg As TransformGroup) As Border
        Dim b As New Border
        With b
            .Width = 100
            .Height = 100
            .Background = Brushes.Red
            .RenderTransformOrigin = New Point(0.5, 0.5)
            .RenderTransform = tg
        End With
        Return b
    End Function

    Private Sub SetBorder(b As Border, x As Double, y As Double)
        Canvas.SetLeft(b, x)
        Canvas.SetTop(b, y)
        canvas1.Children.Add(b)
    End Sub
    Private Sub ChangeAngle(b As Border)
        Dim tg As TransformGroup = b.RenderTransform
        Dim ro As RotateTransform = GetTransform(tg, GetType(RotateTransform))
        ro.Angle = 30
    End Sub


    Private Sub ChangeScale(b As Border)
        Dim tg As TransformGroup = b.RenderTransform
        Dim s As ScaleTransform = GetTransform(tg, GetType(ScaleTransform))
        s.ScaleX = 0.5
        s.ScaleY = 1.2
    End Sub




    Private Sub MainWindow_ContentRendered(sender As Object, e As EventArgs) Handles Me.ContentRendered
        Dim b As Border = GetBorder(ResetRotateScale)
        mihonRotateScale = b
        Call SetBorder(b, 30, 50)

        b = GetBorder(ResetScaleRotate)
        mihonScaleRotate = b
        Call SetBorder(b, 200, 50)
    End Sub


    Private Sub bt1_Click(sender As Object, e As RoutedEventArgs) Handles bt1.Click
        mihonRotateScale.RenderTransform = ResetRotateScale()
    End Sub


    Private Sub bt2_Click(sender As Object, e As RoutedEventArgs) Handles bt2.Click
        Call ChangeAngle(mihonRotateScale)
    End Sub


    Private Sub bt3_Click(sender As Object, e As RoutedEventArgs) Handles bt3.Click
        Call ChangeScale(mihonRotateScale)
    End Sub


    Private Sub bt4_Click(sender As Object, e As RoutedEventArgs) Handles bt4.Click
        mihonScaleRotate.RenderTransform = ResetScaleRotate()
    End Sub


    Private Sub bt5_Click(sender As Object, e As RoutedEventArgs) Handles bt5.Click
        Call ChangeAngle(mihonScaleRotate)
    End Sub


    Private Sub bt6_Click(sender As Object, e As RoutedEventArgs) Handles bt6.Click
        Call ChangeScale(mihonScaleRotate)
    End Sub



    Private Sub sld1_ValueChanged(sender As Object, e As RoutedPropertyChangedEventArgs(Of Double)) Handles sld1.ValueChanged
        Dim tg As TransformGroup = mihonRotateScale.RenderTransform
        Dim r As RotateTransform = GetTransform(tg, GetType(RotateTransform))
        r.Angle = sld1.Value

    End Sub
End Class


コード一式

続いているグループ化のテストの途中で気づいたんだけど、色いろあるねえ
アフィン変換ってのが変形に関わっているみたいなんだけど難しくて諦めた、これが理解できれば今回のことは当たり前なのかも?



ベランダ菜園、いちごの収穫はほぼ終了、トマト(レッドオーレ)に蕾がついた!

$
0
0

トマト(レッドオーレ)B株
イメージ 1
結構大きくなったなあって

イメージ 2
反対側から見たら蕾がついていた!

イメージ 26
昨日の風雨で少し傾いてしまった
最大瞬間風速はたったの8.4m/sだったんだけどねえ


A株
イメージ 10
イメージ 25
B株に追いつくのは難しそうだけど
肥料入れからは成長するようになったなあ

C,D株
イメージ 11
イメージ 24



スイートバジル
イメージ 4
これを

イメージ 6
大きめの雑草を取り除いて

イメージ 3
表面の土を混ぜて化成肥料を少しまいて

イメージ 5
去年のトマトに使っていた黒マルチを流用(横着)
株がまだ小さいのと土が少なすぎてうまく張れない

イメージ 7
斜めにして余分な雨水が右側に寄るようにした
肥料が洗い流されてしまうからプランターの中に雨水を入れたくない

イメージ 8
ここから排水の予定

イメージ 28
イメージ 27


イメージ 14
トマトA株といっしょのスイートバジルは
葉っぱが歪になってきた


ムカデ
イメージ 9
木の棒で半分潰して動けなくしてから撮影
体長1,2センチくらいのが除草やマルチをめくったりすると高確率で遭遇
これも土の熱消毒で居なくなってくれるといいなあ

熱消毒した土
イメージ 12
雨に濡れてほしくないのと熱消毒で使った透明ビニールシートが所在無げだったので
こうなった

イメージ 13
もう一枚の透明シートはここへ

いちご
イメージ 15
腐るゾーンのここから2つ

イメージ 18
このふたつは美味しかった
この日までは8日間降雨がなかったのでひび割れがない

イメージ 21
同じ株の反対側から小さな1つ
これも見た目はこんなだけど美味しかった


イメージ 16
ここから

イメージ 17
中央の赤いの、これはかなりの薄味で美味しくなかった
左右のも見た目的にもイマイチな感じになりそう

イメージ 19
萎びるゾーンまっただ中のここに

イメージ 20
食べられそうなのが2つ
見た目はいいんだけど薄味だった

イメージ 22
上の3つが腐るゾーンから収穫で甘味酸味ともに濃くて美味しかったもの
下の3つが萎びるゾーンからでどれも薄味でいまいち
見た目だと味はわかんないなあ
これで今年のいちごの収穫は終わりかなあ、採れたとしても1個か2個

イメージ 23
今年の適当なまとめ
しなびスギィ
大きなプランターに植わっているのは一昨年の秋から植えっぱなしのもの(A)と
それから伸びたランナーが勝手に定植した形になったもの(B)
苗用の小さなポリポットのものは(A)から伸びたランナーで作った苗を定植できずにそのままになったもの(C)
左下の大きなプランターのは一昨年の秋から植えっぱなしは(A)と同じだけど、一昨年はにんにくと一緒で、去年はトマトと一緒だったもの(D)

(A)花自体が咲かなかったので収穫0
(B)と(C)実は付いたけどしなびたような状態でほとんどが食べられなかった、食べられるものでも味は薄くていまいちだった
(D)去年と同様に実が腐るものが出たけど収穫できたものは今までで一番美味しかった

(D)だけが他と違うのは去年トマトと一緒だったので肥料が十分だったってのかなあ
トマトに追肥するときは隣の子のイチゴは肥料が多すぎで枯れてしまうんじゃないかと思いながらしていた
12月くらいでトマトが枯れてからは春に1回追肥しただけだから、夏や秋にも放置しないで肥料を入れてあげるのが大切なのかも

収穫数というか収穫率でいうと今年は最悪だったけど(D)の味は良かった
去年は腐りまくったけど萎びるのは少なくて味はちょっと薄味だけど美味しいね
一昨年は1株だけ残った全滅状態からの復活中だったので収穫0
一昨々年は普通に美味しいねくらいだったかな


ベランダ菜園、トマト(レッドオーレ)定植、今季のいちごの収穫は終わり、環境の違いによる成長の差

$
0
0

トマト(レッドオーレ)B株
イメージ 2
イメージ 3
脇芽がたくさん出てきたので

イメージ 4
摘みとった

イメージ 11
赤いアブラムシ

A株
イメージ 12
これをB株のプランターに定植することにした

イメージ 15
スイートバジルの葉っぱが虫食い状態になっていた

イメージ 16
裏側見たらフンらしきものはあったけど本体は見当たらず

イメージ 17
トマトの葉っぱの裏にはアブラムシが結構いた

イメージ 18
位置合わせ

イメージ 19
ポットから取り出す
この時ムカデが出てくることがあるから、そのためのゴム手袋!
でも今回は居なかったみたい

イメージ 20
設置

イメージ 21
やっぱ大きさぜんぜん違う
A株のほうが2日早く発芽したのに環境の差だねえ
今のところの感想だとレッドオーレは種を直播でいいのかも

手袋
イメージ 14
手のひら側はゴム

イメージ 13
手の甲側は布地
通気性があるので全部ゴムよりは涼しいはず

雨上がり直前のトマト
イメージ 22
イメージ 23
イメージ 24
もう止んだかと思って外に出たら霧雨状態だった

イメージ 28
葉っぱだと見間違えて取り除かなかった脇芽

イメージ 29
摘み取って

イメージ 30
A,B株の間に刺して

イメージ 37
1日経ったけど萎れてはいなかった

イメージ 38
第2花房も出てきた、第1花房は開花が近そう

イメージ 39



イメージ 5
去年のこぼれ種からのC,D株

イメージ 31
C株は成長している感じあるけどD株はあんまり変化ない



いちご腐るゾーン最後の1個
イメージ 6
昨日の雨のせいかなあ、これは廃棄ルートかも
この次の日も雨が降って

イメージ 25
イメージ 26
こうなって、翌日には

イメージ 32
こんなに干からびていたw


いちご萎びるゾーン
イメージ 8

手前の
イメージ 9
左のひび割れているのを収穫
この株から前回収穫したものはかなりの薄味だったけど
今回のはいい味だった

奥側の
イメージ 10
下に写っている2つは廃棄、上のはもう少し

イメージ 27
雨降り後だと割れちゃうなあ
トマトみたいに内側から膨らんで割れるんじゃなくて
外側から削られたようになる
見た目は良くないけど美味しかった
たぶんこれが今年最後の収穫になるかなあ

イメージ 33
残っているのはこの2つだけどムリそうね

イメージ 36
花がつかなかった株からはランナーが伸びてきた

スイートバジル
イメージ 1
イメージ 7
脇芽が伸びていた

イメージ 34
イメージ 35
イメージ 40
発芽した日はトマトA株と一緒の株のほうが
だいぶ早かったんだよねえ
小さなポリポットと大きなプランターっていう環境の差
虫に食べられるか食べられないかっていう運の差


WPFとVB.NET、エクセルのグループ化とグループ化解除を真似したい3

$
0
0

以前とは別の方法でグループ化と解除のテスト
イメージ 1


デザイン画面とXAML
イメージ 2

VBコード
イメージ 17

Imports System.Windows.Controls.Primitives


Class MainWindow
    Private tList2 As New List(Of ExThumb2)
    Private Const grid As Integer = 20 'グリッドの大きさ


    '選択中のExThumb
    Private Property _FocusThumb As ExThumb2
    Private Property FocusThumb As ExThumb2 '選択中のThumb
        Get
            Return _FocusThumb
        End Get
        Set(value As ExThumb2)
            _FocusThumb = value
            tbk1.Text = "FocusThumb = " & value.Name
            If value.GroupTop IsNot Nothing Then
                tbk2.Text = "FocusGroup = " & value.GroupTop.aName
            Else
                tbk2.Text = "FocusGroup = Nothing"
            End If
        End Set
    End Property


    'ExThumbの座標セット
    Private Sub SetLocate(obj As Object, p As Point)
        Canvas.SetLeft(obj, p.X)
        Canvas.SetTop(obj, p.Y)
    End Sub
    'ExThumbの座標ゲット
    Private Function GetLocate(obf As FrameworkElement) As Point
        Return New Point(Canvas.GetLeft(obf), Canvas.GetTop(obf))
    End Function

    'ExThumbのマウスドラッグイベント用
    Private Sub ThumbDragDelta(sender As Object, e As DragDeltaEventArgs)
        Dim t As ExThumb2 = DirectCast(sender, ExThumb2)
        Dim x As Double = e.HorizontalChange
        Dim y As Double = e.VerticalChange
        x -= x Mod grid
        y -= y Mod grid

        Dim np As New Point(x, y)

        'グループ用
        If t.GroupTop IsNot Nothing Then
            For Each tt As ExThumb2 In t.GroupTop.AllItems
                Call SetLocate(tt, GetLocate(tt) + np)
            Next
        Else
            Call SetLocate(t, GetLocate(t) + np)
        End If
    End Sub

    'ExThumbのマウスクリックイベント用
    Private Sub FocusThumb_PreviewMouseDown(sender As Object, e As MouseButtonEventArgs)
        'FocusThumbの切り替え
        Dim t As ExThumb2 = DirectCast(sender, ExThumb2)
        FocusThumb = t
    End Sub






    Private Sub AddExThumb2(count As Integer)
        '10個ExThumb2作成
        For i As Integer = 0 To count
            Dim t As New ExThumb2(i, New Size(grid * 2, grid * 2))

            SetLocate(t, New Point(grid * i, grid * i))
            canvas1.Children.Add(t)
            tList2.Add(t)
            AddHandler t.DragDelta, AddressOf ThumbDragDelta
            AddHandler t.PreviewMouseDown, AddressOf FocusThumb_PreviewMouseDown
            FocusThumb = t
        Next
    End Sub

    'tの中のGroup取得、重複除く、Nothing除く
    Private Function GetAllGroup2(tl As List(Of ExThumb2)) As List(Of Group2)
        Dim gl As New List(Of Group2)
        For Each t As ExThumb2 In tl
            If t.GroupTop IsNot Nothing Then
                gl.Add(t.GroupTop)
            End If
        Next
        gl = gl.Distinct.ToList
        Return gl

    End Function

    'Groupに属していない単体のtを返す
    Private Function GetSimpleExThumb(tl As List(Of ExThumb2)) As List(Of ExThumb2)
        Dim nl As New List(Of ExThumb2)
        For Each t As ExThumb2 In tl
            If t.GroupTop Is Nothing Then
                nl.Add(t)
            End If
        Next
        Return nl
    End Function


    'グループ化
    Private Sub AddGroup(tl As List(Of ExThumb2), i As Integer)
        '渡されたThumbをグループ化する
        'トップグループが1つの場合は統合
        '0か2以上ならグループを新規作成してそれに全部入れる
        If tl.Count <= 1 Then Return
        Dim gl As List(Of Group2) = GetAllGroup2(tl) 'Groupのカウント用
        Dim st As List(Of ExThumb2) = GetSimpleExThumb(tl) 'Groupに属していないthumb
        Dim g As Group2
        If gl.Count = 1 Then
            '統合の場合
            g = gl(0)
            g.Items.AddRange(st) 'Groupに属していないtを追加
            g.AllItems.AddRange(st) '全部取得用リスト
            For Each t As ExThumb2 In st
                t.GroupTop = g
            Next
        Else
            '新規作成の場合
            g = New Group2(i)
            g.Groups = gl
            g.Items.AddRange(st) 'Groupに属していないthumbを追加
            '全thumb取得用リスト
            Dim allt As New List(Of ExThumb2)
            allt.AddRange(st)
            For Each gg As Group2 In gl 'リスト作成
                allt.AddRange(gg.AllItems)
            Next
            allt = allt.Distinct.ToList '重複除去
            g.AllItems = allt
           For Each t As ExThumb2 In tl
            For Each t As ExThumb2 In allt
                t.GroupStack.Push(t.GroupTop) 'グループ階層記録用
                t.GroupTop = g
            Next
        End If

    End Sub


    'グループ化解除
    Private Sub ungroup2_1(gg As Group2)
        If gg Is Nothing Then Return

        'Groupの底上げ
        For Each t As ExThumb2 In gg.AllItems
            If t.GroupStack.Count = 0 Then
                t.GroupTop = Nothing
            Else
                Dim g As Group2 = t.GroupStack.Pop
                t.GroupTop = g
            End If
        Next

    End Sub


    'WPF: XAML, C# で TextBlock などの要素内の文字列を改行させる « をぶろぐ
    'http://tetsuwo.tumblr.com/post/59191241888/wpf-xaml-csharp-textblock-break-word-wrap

    Private Sub DrawTextblock()
        Dim tb As New TextBlock
        Dim nl As String = Environment.NewLine
        tb.Text = "初期状態グループの構造" & nl & "G5" & nl & "┣G3" & nl & "┃┣G1" & nl & "┃┃┣t0" & nl &
            "┃┃┗t1" & nl & "┃┣G2" & nl & "┃┃┣t2" & nl & "┃┃┗t3" & nl &
            "┃┣t4" & nl & "┃┗t5" & nl & "┗G4" & nl & " ┣t6" & nl &
            " ┣t7" & nl & " ┣t8" & nl & " ┗t9"
        canvas1.Children.Add(tb)
        Panel.SetZIndex(tb, -1)
    End Sub

    Private Sub ReSet()
        Call AddGroup(tList2.GetRange(0, 2), 1) 'g1(0,1)、        t0,t1をグループ化、名前はg1
        Call AddGroup(tList2.GetRange(2, 2), 2) 'g2(2,3)
        Call AddGroup(tList2.GetRange(0, 4), 3) 'g3(g1,g2)、      g1とg2をグループ化、名前はg3
        Call AddGroup(tList2.GetRange(0, 6), 4) 'g3(g1,g2,4,5)、  g3にt4とt5を追加
        Call AddGroup(tList2.GetRange(6, 2), 4) 'g4(6,7)
        Call AddGroup(tList2.GetRange(6, 4), 4) 'g4(8,9)
        Call AddGroup(tList2, 5)                'g5(g3,g4)、      g3とg4をグループ化、名前をg5
    End Sub


    'E:\オレ\エクセル\WPFでPixtack紫陽花.xlsm_配置_$Q$437
    Private Sub MainWindow_ContentRendered(sender As Object, e As EventArgs) Handles Me.ContentRendered
        'Call DrawGridLine()
        'Panel.SetZIndex(canvas1, -1)
        Call AddExThumb2(9) 't0からt9までの10個のExThumb2を作成してリストに入れる
        Call ReSet()
        Call DrawTextblock()

    End Sub
    'リセット
    Private Sub bt1_Click(sender As Object, e As RoutedEventArgs) Handles bt1.Click
        Call ReSet()
    End Sub


    '選択中のtを含むグループを解除
    Private Sub bt2_Click(sender As Object, e As RoutedEventArgs) Handles bt2.Click
        Call ungroup2_1(FocusThumb.GroupTop)
    End Sub

End Class



Public Class ExThumb2
    Inherits Thumb
    Public Property GroupTop As Group2 '全体
    'グループ化するときに元のグループをスタックしていって
    'グループ化解除するときに取り出してGroupTopに据えるGroupStack
    Public Property GroupStack As New Stack(Of Group2)

    Public Sub New(i As Integer, s As Size)
        Me.Name = "t_" & i
        Me.Template = GetTemplate() 'Template指定
        Me.ApplyTemplate() 'Template再構築実行

        Dim b As New Border With {
            .Background = Brushes.Cyan,
            .BorderBrush = Brushes.Black,
            .BorderThickness = New Thickness(1),
            .Width = s.Width, .Height = s.Height}
        Dim tb As New TextBlock With {.Text = "t" & i}
        Canvas.SetLeft(tb, 10)

        Dim c As Canvas = DirectCast(Me.Template.FindName("cc", Me), Canvas)
        c.Children.Add(b)
        c.Children.Add(tb)
    End Sub


    'Template作成
    'WPFとVB.NET、ControlTemplateをコードで作成 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
    'http://blogs.yahoo.co.jp/gogowaten/14156250.html
    Private Function GetTemplate() As ControlTemplate
        Dim ct As New ControlTemplate
        ct.VisualTree = New FrameworkElementFactory(GetType(Canvas), "cc")
        Return ct
    End Function
End Class


Public Class Group2
    Public Property Items As New List(Of ExThumb2)
    Public Property AllItems As New List(Of ExThumb2) 'すべてを取得する時用
    Public Property Groups As List(Of Group2)

    <System.ComponentModel.Category("name")>
    Public Property aName As String
    Public Sub New(i As Integer)
        aName = "G_" & i
    End Sub
End Class



#Region "Group3(未使用)"
Public Class Group3
    Inherits List(Of ExThumb2)
    Public Property Groups As List(Of Group3)
    <System.ComponentModel.Category("name")>
    Public Property aName As String
    Public Sub New(i As Integer)
        aName = "G_" & i
    End Sub
End Class
#End Region



前回までの方法だとうまく解決できない問題が出た
イメージ 16

イメージ 3
1→2→5の後にグループ化解除なら問題なけど、1から5までの順番だと6で縦横の拡大率がおかしくなる
これは各画像の表示を
Thumb.Template
┗Canvas
┗Image
こうしていて、グループ化した時は
Thumb.Template(c)
┗Canvas
┣Thumb.Template(a)
┗Canvas
┗Image
┗Thumb.Template(b)
┗Canvas
┗Image
こうなっていて
グループ化解除時に回転や拡大率の変形情報の引き継ぎがうまくできていないのがおかしくなる原因みたい
解決するのは難しそうだったので別の方法が今回のもので
グループ化は擬似的なものに変更したのが大きな違い
前回はグループ化するごとにThumbが増えていったけど、今回のは増やさないでどれとどれが同じグループですっていうグループ情報を各Thumbに持たせることにした
あるThumbを回転させるときグループに属していたら同じグループ内のThumb全部も同じように回転させる

そのグループ情報はこの部分、Group2って名前をつけたClassを作成
イメージ 4
Itemsにはグループ直下のThumbすべてを入れる、グループ化解除の時使う
AllItemsはグループ全体に入っているThumbすべてを入れる
これを使えば移動や変形の指定をグループ全体のThumbにできる
Groupsはこのクラス自体のリスト、グループ同士をグループ化した時に使う
aNameはただの識別用の名前を入れるだけのもの

このGroup2を持たせるのがThumbを継承させたExThumb2って名前をつけたこれ
イメージ 5
201行目にあるGroupTopにGroup2を入れる
これでGroupTop.AllItemsってすれば自分が属しているグループ全体のThumbすべてを取得できる
204行目はグループ化解除の時に活躍、CollectionのStackっていうもので初めて使うもの、これが面白い動きをしてアイテムを追加するのは他のリストとあんまり変わらないけど、取り出すときは最後に入れたものから取り出して、取り出したアイテムをリストに残すか削除するかを選べる
205行目以降は装飾的なものなのでグループ化とは関係ないところ


グループ化
※tはExThumb2を表す、Gはグループを表す
どのtをグループ化するのかって指定するからグループ化メソッドの引数は複数のtになる

グループ化の種類
  1. t同士をグループ化
  2. 複数Gのグループ化
  3. 単体Gとtをグループ化
1と2の時は新しいグループを作成
3の時は単体Gにtを統合(入れる)、つまり新しくグループを作成しない
これを判定するには引数のtにグループがいくつあるのか取得する必要がある
それがGetAllGroup2って名前をつけたこれ
イメージ 7
すべてのt.GroupTopをリストに追加して
85行目でDistinctメソッドで重複のないのが得られる
これで渡されたtに含まれる重複のないすべてのG取得

グループ直下に加えるtを取得する
イメージ 8

上のふたつを使って実際のグループ化の処理
イメージ 11
作成、または統合したGroup2(グループ情報)を渡されたすべてのThumbのGroupTopに設定する
131行目が重要、新しいGを作ったので今までのGは1階層下になるのでGroupStackプロパティにPushメソッドで今までのGを追加、これによって解除するときは1階層上げることになるのでその時取り出しやすくなる
132行目、新しいGをGroupTopプロパティに指定する


グループ化したいtを渡す
イメージ 6
tList2にはすべてのExThumb2が入っているリストになる
この中からグループ化したいtを指定して渡す
ここでは最終的にt0からt9までの10個全てをグループ化している
イメージ 12
左が初期状態から右端は174行目の処理が終わった時の状態

GetRangeメソッドはリストから指定範囲のアイテムを取り出してくれる
(0,2)なら0番から2個分の0と1
(2,2)なら2番から2個分の2と3
(6,4)なら6番から4個分の6,7,8,9


グループ化解除
イメージ 9
解除するときは解除したいGを渡して処理

G3を解除する場合
イメージ 10
左から右状態になればいい

t4とt5はG3直下で下の階層GはないのでGroupStackプロパティには何も入っていない=0、なのでGroupTopを削除するだけでいい、これが145行目
t0,t1はG1、t2,t3はG2がそれぞれGroupStackに入っているので
147行目でGroupStackのPopメソッドで下階層だったGを取り出して
148行目でGroupTopプロパティに指定
Popメソッドは最後に入れたものから取り出して、取り出したアイテムはStackから削除してくれる


イメージ 13
初期状態
すべてのtはG5に入っているので
どのtを選択しても選択GはG5になるし
どれをマウスドラッグ移動しても全部まとまって動く
ここで選択グループを解除すると

イメージ 14
G5が解除されてG3,G4に別れる
t6からt9のどれかをクリックしてから解除すると

イメージ 15
G4が解除されてt6からt9は別々にドラッグ移動できるようになる
どのグループにも属していないのでNothingになる

今回はここまでで肝心な回転とかの変形はまだなんだよねえ
前回の記事から10日くらい経っているんだなあ
Public Class Group2
    Public Property Items As New List(Of ExThumb2)
    Public Property AllItems As New List(Of ExThumb2) 'すべてを取得する時用
    Public Property Groups As List(Of Group2)
End Class
これにたどり着くまで時間がかかった、とくに
    Public Property Groups As List(Of Group2)
これ、自分と同じClassをプロパティに持つってのがね、なんかこれでいいのかなってムズムズする、無限ループみたい


今回参照したところ
WPF: XAML, C# で TextBlock などの要素内の文字列を改行させる « をぶろぐ
http://tetsuwo.tumblr.com/post/59191241888/wpf-xaml-csharp-textblock-break-word-wrap
感謝!



今回のコード一式

前回までの方法(なんか違う)のコード一式


関連記事、古い順
WPFとVB.NET、エクセルのグループ化を真似したいからまずはグループ化のRectを取得 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14151447.html

WPFとVB.NET、ControlTemplateをコードで作成 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14156250.html

前回の記事
WPFとVB.NET、エクセルのグループ化とグループ化解除を真似したい2 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14161262.html

2016年6月3日追記
WPFとVB.NET、マウスドラッグ移動で範囲選択、枠表示して枠内のものを取得 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14190065.html

130行目をこっそり修正
誤            For Each t As ExThumb2 In tl
正            For Each t As ExThumb2 In allt



WPFとVB.NET、マウスドラッグ移動で範囲選択、枠表示して枠内のものを取得

$
0
0

マウスドラッグ移動で四角枠を表示して枠内のThumbを取得

イメージ 1


デザイン画面とXAML
イメージ 2
マウスの位置を取得するには背景色を指定する必要があるみたい
だけど色はいらないので透明色のTransparenを指定している

VBコード
イメージ 3

Imports System.Windows.Controls.Primitives

Class MainWindow
    Private syoki As Point '選択範囲枠の初期位置記録用
    Private IsDrag As Boolean 'canvas1上でマウスドラッグ移動判定用
    Private waku As Path '選択範囲枠
    Private tList As New List(Of Thumb) 'すべてのThumbを入れておくリスト

    '渡されたThumbを指定された位置に移動
    Private Sub SetLocate(ele As UIElement, p As Point)
        Canvas.SetLeft(ele, p.X)
        Canvas.SetTop(ele, p.Y)
    End Sub

    '渡されたThumbの位置を返す
    Private Function GetLocate(ele As UIElement) As Point
        Dim x As Double = Canvas.GetLeft(ele)
        Dim y As Double = Canvas.GetTop(ele)
        Return New Point(x, y)
    End Function

    'Thumbのドラッグ移動用
    Private Sub DragDelta(sender As Object, e As DragDeltaEventArgs)
        Dim t As Thumb = DirectCast(sender, Thumb)
        Dim p As Point = GetLocate(t)
        Dim nx As Double = e.HorizontalChange + p.X
        Dim ny As Double = e.VerticalChange + p.Y
        nx = nx - (nx Mod 20)
        ny = ny - (ny Mod 20)
        SetLocate(t, New Point(nx, ny))
    End Sub

    'Thumbを10個作成
    Private Sub AddThumb()
        Dim t As Thumb
        For i As Integer = 0 To 9
            t = New Thumb With {
                .Width = 60, .Height = 60, .Background = Brushes.Aqua}
            Canvas.SetLeft(t, i * 20) : Canvas.SetTop(t, i * 20 + 20)
            AddHandler t.DragDelta, AddressOf DragDelta
            tList.Add(t)
            canvas1.Children.Add(t)
        Next
    End Sub




    '選択範囲内のThumbの色を赤に変える
    'RectクラスのIntersectsWithメソッドを使う
    Private Sub SelectThumb()
        Dim sr As Rect = waku.Data.Bounds '枠のRect
        Dim tr As Rect
        For Each t As Thumb In tList
            tr = New Rect(GetLocate(t), t.RenderSize) 'ThumbのRect
            'ThumbのRectが枠のRectと重なっているか判定
            If tr.IntersectsWith(sr) Then
                '重なっていたら赤
                t.Background = Brushes.Red
            End If
        Next
    End Sub


    '選択範囲枠用のPathデータ作成
    Private Sub SetPathData(p As Point)
        Dim r As New Rect(syoki, p)
        Dim gp As New RectangleGeometry(r)
        waku.Data = gp
    End Sub

    'アプリ起動中
    Private Sub MainWindow_Initialized(sender As Object, e As EventArgs) Handles Me.Initialized
        Call AddThumb() 'Thumbを作成
    End Sub

    'アプリ起動完了後
    Private Sub MainWindow_ContentRendered(sender As Object, e As EventArgs) Handles Me.ContentRendered
        '範囲選択枠の設定
        waku = New Path With {.Stroke = Brushes.Red, .StrokeThickness = 1.0R}
    End Sub

    'canvas1上で左クリック時
    Private Sub canvas1_MouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs) Handles canvas1.MouseLeftButtonDown
        Dim c As Canvas = DirectCast(sender, Canvas)
        syoki = e.GetPosition(c)
        c.CaptureMouse()
        waku.Data = New RectangleGeometry() '枠データの初期化
        canvas1.Children.Add(waku)
        IsDrag = True
    End Sub

    'canvas1上でマウス移動時
    Private Sub canvas1_MouseMove(sender As Object, e As MouseEventArgs) Handles canvas1.MouseMove
        If IsDrag = False Then Return
        Dim imap As Point = e.GetPosition(canvas1)
        Call SetPathData(imap) '範囲選択枠データの更新
    End Sub

    'canvas1上で左クリック離した時
    Private Sub canvas1_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles canvas1.MouseLeftButtonUp
        If IsDrag = False Then Return
        Call SelectThumb() '選択範囲内のThumbを赤にする
        Dim c As Canvas = DirectCast(sender, Canvas)
        IsDrag = False
        c.ReleaseMouseCapture()
        canvas1.Children.Remove(waku) '選択範囲枠の消去
    End Sub

    'Thumbの色を初期化、アクアにする
    Private Sub bt1_Click(sender As Object, e As RoutedEventArgs) Handles bt1.Click
        For i As Integer = 0 To tList.Count - 1
            tList(i).Background = Brushes.Aqua
        Next
    End Sub
End Class



イメージ 4
syoki
枠の位置と大きさはマウスドラッグ移動開始位置と今の位置で決めるので
開始位置(初期位置)を記録しておく必要がある
IsDrag
マウスドラッグ移動中かどうかの判定用
waku
赤枠はPathで描く、マウスドラッグ移動による大きさ変更はPath.Dataの変更で行う
表示非表示の切り替えはChildren.Add(waku)とChildren.Remove(waku)で行う
tList
すべてのThumbの入れ物

渡されたUIElementの位置(Point)を返す
GetLocate
イメージ 10
ただ単にCanvas.GetLeftとCanvas.GetTopで取得した値を
Pointにして返しているだけ
今思ったけど3行も書かなくても
Return New Point(Canvas.GetLeft, Canvas.GetTop)
こう書けば1行で済むじゃん
1行で済むならわざわざメソッドにしなくても良さそうなんだけど
GetLeftもGetTopもタイプしづらい、GetLocateはタイプしやすい

Path.Dataの変更をする
SetPathDataメソッド
イメージ 7
渡された位置(p)と初期位置(syoki)を使って
サイズと位置を指定した四角形(Rect)を作成
四角形を使ってPathの四角形データになるRectangleGeometryを作成
waku(Path).Dataに四角形データを指定する


赤枠に少しでも触れているThumbすべてを取得して赤色に変える
SelectThumb
イメージ 9
48行目、Path.Data.Boundsで赤枠のRect(位置とサイズ)が取得できる
For Eachを使ってすべてのThumbと重なっている(触れている)かどうか判定
Thumbの位置はGetLocateで取得
サイズはRenderSizeプロパティから取得して
これを使ってRectを作成、51行目
枠のRectとThumbのRectを比較しているのが53行目で
RectクラスのIntersectsWithっていうメソッドを使っている
これが便利なもので渡した2つのRectが少しでも重なるようならTrueを返して
そうでなければFalseを返してくれる
55行目で赤色に変える



canvas1上で左クリック時(マウスドラッグ移動開始時)
イメージ 5
GetPositionメソッドでクリック位置の記録、78行目
81行目でcanvas1に枠表示されるけど80行目でデータが0になっているので実質的に非表示のはず
82行目はマウスドラッグ移動中ですよフラグ

マウス移動中
イメージ 6
マウスドラッグ移動中ではない状態ならなにもしないで終了
マウスドラッグ移動中なら
今のマウスの位置をGetPositionメソッドで取得して
SetPathDataへ渡してPath.Dataの変更(枠の大きさ変更)

canvas1上で左クリック離した時(マウスドラッグ移動終了時)
イメージ 8
左クリックを離したら赤枠に重なっているThumbを赤色にするために
SelectThumbメソッドを実行、93行目
赤枠の消去が97行目




グループ化するときにはどれをグループ化するのか複数の対象を選択する必要があるので作ってみた
マウスドラッグ移動で選択する他によくあるのはctrlキーを押しながらクリックとかあるけど難しそうなので見送ったw


今回のコード全部

関連記事、古い順
前回
WPFとVB.NET、エクセルのグループ化とグループ化解除を真似したい3 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14187560.html




WPFとVB.NET、エクセルのグループ化とグループ化解除を真似したい4

$
0
0
グループ化の続き
前回と前々回のを足して
グループ化したいThumbをマウスのドラッグで範囲選択してグループ化と解除
ここまでできた
イメージ 1
青枠はグループの枠でただの目印

回転角度と拡大率指定のスライダーはまだ動かせない、これができたらテストはほぼ終了なんだけどねえ

デザイン画面とXAML
イメージ 2


VBコード
イメージ 4
今回はコードの文字数がブログの上限を超えてしまったので画像だけ

グループ化の方法を少し変更した
前回は既存のグループと単体のThumbをグループ化するときは、既存のグループにThumbを足す形にしていたけど、別グループを新規作成してそこに既存のグループとThumbを入れるようにした
グループ1(t1, t2) + t3, t4のとき
前回 グループ1(t1, t2, t3, t4)
今回 グループ2(グループ1(t1, t2), t3, t4)
グループ化解除した時は今回のほうが自然な感じなんだけど、前回は気づかなくて余計なことをしていたw


グループの枠表示
グループに属しているThumbをクリックした時に、そのグループが収まる青枠を表示するようにした、目印用
イメージ 3
枠の表示にPathクラスとRectangleGeometryを使うのは前回の範囲選択の赤枠の表示と同じ方法、このPathはWakuって名前にした、586行目
枠の位置や大きさになるRectはBoundって名前にした、このBoundの値を変更するときに同時にWakuのDataも更新するようにした、598行目
この2つをGroup2に持たせた。
さっきのグループ化の方法変更でグループ直下のThumbリストは意味がなくなったので廃止、583行目

グループの枠の表示の切り替えタイミングは
選択Thumbを切り替えた時
グループ化した時
グループ化解除した時
この3つ
選択グループが変わった時ってことで
イメージ 5
ActiveGroupって名前のGroup2のプロパティを用意して(55行目)
この値を変更(Set)した時に枠の表示も切り替えることにした(60行目から)
今思った
枠を表示するときはCanvas.Children.Add
非表示にするときはCanvas.Children.Remove
っていう追加と削除で行っているけど
表示value.Waku.Visibility = Visibility.Visible
非表示value.Waku.Visibility = Visibility.Collapsed
文字通りこっちのほうがいいかも?


今回のコード全部は

関連記事
前々回
WPFとVB.NET、エクセルのグループ化とグループ化解除を真似したい3 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14187560.html
前回
WPFとVB.NET、マウスドラッグ移動で範囲選択、枠表示して枠内のものを取得 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14190065.html



Viewing all 420 articles
Browse latest View live