WPF習作メモ

blog20191215-WPFTest1

地図などを背景にして、印を上に書き加えることを想定してます。データはグループ(Group)配列とそれぞれに位置データ(Spot)配列の階層構造になってます。例えばグループとして、レストラン・コンビニなどの業種、Spotとしては店の位置とその規模を円の大きさで示すなど。あとエスコンのレーダーかいくぐりミッションとか

コードは以下のことができます。

  • 左のリスト
    • データグループ名(0~4)を表示
    • 行を選択すると対応するグループに属する円を黄色にする
  • 右のチャート
    • 各Spotデータが示す位置に円を描画、円の中央にはグループ名
    • 円の上にカーソルを置くと同じグループに属する円が太くなる
    • 円をクリックするとそのグループが選択状態になり黄色に、また左のリストの選択もそれに対応する

左はいたって普通のListBoxですが、右もListBoxです。ListBoxをカスタマイズするにしても通常ItemsPanelにはStackPanelやWrapPanelを指定するでしょうが、ここではCanvasを使うことで自由な位置への配置を可能にします。その代わり位置を指定しないと全部左上に重なってしまうので、ItemContainerStyleでCanvas.LeftとCanvas.Top添付プロパティを設定します。

同一グループ内の複数の円を描くにはItemsControlを使用。ItemsControlはListBoxの親クラスです。ListBoxを使用すると同一グループ内の個々の円に対する選択が発生してしまうのでこちらを使用してますが、用途によってはListBoxでも可。つまりListBoxの中にListBoxを使っていることになります。下の図でいえば、左のListBoxで選択状態にある"0"に相当するのが、右の黄色箱で囲んだ部分になります。左右とも同じデータをバインディングしたListBox、描画方法が違うだけ。

左右で選択が連携するのは簡単、左のSelectedItemを右のSelectedItemにTwoWayでバインドするだけ。下図の黄色箱どこでもクリックすれば左のListBoxの0の行をクリックしたのと同じはずですが、黄色箱のItemsPanelとなっているCanvasはマウスイベントを拾わないので、円内部だけがクリックに反応します。

無理やりな部分があまりないので転用しやすいと思います。これだけのことがXAMLだけで実現できてしまうとは、面白い技術だなと。

blog20191215-WPFTest2

XAML
<Window x:Class="RxMouseDragTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <DataTemplate x:Key="GroupListItemTemplate">
            <TextBlock Text="{Binding GroupNumber}"/>
        </DataTemplate>
        
        <DataTemplate x:Key="SpotTemplate">
            <Grid>
                <TextBlock Text="{Binding Number}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White"/>
                <Ellipse Width="{Binding Width}" Height="{Binding Height}" Fill="Transparent">
                    <Ellipse.Style>
                        <Style TargetType="{x:Type Ellipse}">
                            <Setter Property="Stroke" Value="Red"/>
                            <Setter Property="StrokeThickness" Value="3"/>
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding IsSelected,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ContentControl}}" Value="true">
                                    <Setter Property="Stroke" Value="Gold"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding IsMouseOver,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ContentControl}}" Value="true">
                                    <Setter Property="StrokeThickness" Value="6"/>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Ellipse.Style>
                </Ellipse>
            </Grid>
        </DataTemplate>
        <Style x:Key="SpotContainerStyle" TargetType="{x:Type ContentPresenter}">
            <Setter Property="Canvas.Left" Value="{Binding Left}"/>
            <Setter Property="Canvas.Top" Value="{Binding Top}"/>
        </Style>

        <ItemsPanelTemplate x:Key="GroupPanelTemplate">
            <Canvas Background="Transparent"/>
        </ItemsPanelTemplate>        
        <DataTemplate x:Key="GroupTemplate">
            <ItemsControl
                ItemsSource="{Binding Spots}"
                ItemTemplate="{StaticResource SpotTemplate}"
                ItemContainerStyle="{StaticResource SpotContainerStyle}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </DataTemplate>
    </Window.Resources>
    
    <Grid Background="Black" ClipToBounds="True">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <ListBox Name="GroupList" Grid.Column="0" ItemsSource="{Binding Groups}" ItemTemplate="{StaticResource GroupListItemTemplate}"/>
        <ListBox
            Name="ChartBase"
            Grid.Column="1"
            ItemsPanel="{StaticResource GroupPanelTemplate}"
            ItemTemplate="{StaticResource GroupTemplate}"
            ItemsSource="{Binding Groups}"
            SelectedItem="{Binding SelectedItem,ElementName=GroupList}"
            Background="{x:Null}">
        </ListBox>
    </Grid>
</Window>
コード。DataContextをセットしているだけです。
public partial class MainWindow : Window
{
    static readonly Random rnd = new Random();

    public MainWindow()
    {
        InitializeComponent();

        DataContext = new
        {
            Groups = Enumerable.Range(0, 5).Select(i => new SpotGroup(i, rnd.Next(1, 4))),
        };
    }
}

public class SpotGroup
{
    public int GroupNumber { get; private set; }
    public IEnumerable<Spot> Spots { get; private set; }

    public SpotGroup(int GroupNumber, int NumItems)
    {
        this.GroupNumber = GroupNumber;
        Spots =
            Enumerable.Range(0, NumItems)
            .Select(i => new Spot() { Number = GroupNumber })
            .ToArray();
    }
}

public class Spot
{
    static readonly Random rnd = new Random();

    public int Number { get; set; }
    public int Left { get; private set; }
    public int Top { get; private set; }
    public int Width { get; private set; }
    public int Height { get; private set; }

    public Spot()
    {
        Left = rnd.Next(0, 300);
        Top = rnd.Next(0, 250);
        Width = rnd.Next(0, 20) + 40;
        Height = rnd.Next(0, 20) + 40;
    }
}

— posted by mu at 09:34 pm   commentComment [0]  pingTrackBack [0]

トミカのカはCarだと思ってた

20191208-TomicaPremium_F35A
Tomica Premium #28

トミカプレミアム 28番 F-35A戦闘機。東京モーターショーのイメージもあってか、店で見かけたこれがトミカと名乗っていることに感じる所があり購入。この品質で750円程度は安いと思うのは私が大人になってしまったからでしょう。

F-16/F-2もですが単発機は胴体が厚ぼったくなってしまい、見る方向によっては不格好に感じる。ラインナップで軍用機は自衛隊機に限っているようなので望み薄ですが、ここはF-22Aを製品化していただきたい。

— posted by mu at 11:52 pm   commentComment [0]  pingTrackBack [0]

WindowsでDisk is full

前回Link の続き。数時間後にまたDisk fullで不具合。MySQL以外のプログラムでもDisk fullが出たのでMySQL固有の問題ではなさそう。

このマシン、ドライブの構成は以下のようになってました。

C:¥ (NTFS)
+- ProgramData
   +- MySQL
      +- 10TBの別Volume (ReFS)

記憶域プールで作成した10TBのReFSドライブにはドライブレターを割り当てず、C:¥ProgramData¥MySQLにマウントしてました。

コマンドラインや記憶域プールマネージャーで見る限りReFSドライブにはまだ8TB以上空きがありますが、複数のプログラムでDisk fullエラーが出ている以上、Windowsが空き容量を誤認している可能性が高い。NTFSへのReFSのマウント、あまりメジャーでない構成を使ったのがいけなかったか。

というわけで、ReFSのC:¥ProgramData¥MySQLマウントは解除、ドライブレターを与えJunctionでつないで様子見することに。今度は解決してほしいなと。

ちなみにOSはWindows Server 2016 (1607)です。

[2019/7/1] Windowsバージョン訂正

[2019/7/2] ダメでした

[2019/7/3] 記憶域プールから別のディスク作って、MySQL止めて、データ全コピ。とりあえず問題起こした仮想ディスクは残しておいて…調べる暇ないだろうな(^ ^;)

— posted by mu at 12:13 pm   commentComment [0]  pingTrackBack [0]

Windows MySQL8.0でDisk is full

昨晩からMySQLがクライアントとの接続を切断するようになり、今朝MySQLを再起動しようとすると起動しなくなる。ログを見るとそれ以前から何か起きてそうですが、とりあえず直近は

2019-06-28T02:13:31.236234Z 0 [System] [MY-010116] [Server] C:¥Program Files¥MySQL¥MySQL Server 8.0¥bin¥mysqld.exe (mysqld 8.0.11) starting as process 1424
2019-06-28T02:13:36.590942Z 1 [ERROR] [MY-012644] [InnoDB] InnoDB: Encountered a problem with file '.¥ibtmp1'
2019-06-28T02:13:36.592011Z 1 [ERROR] [MY-012645] [InnoDB] InnoDB: Disk is full. Try to clean the disk to free space.
2019-06-28T02:13:36.593191Z 1 [ERROR] [MY-012267] [InnoDB] InnoDB: Could not set the file size of '.¥ibtmp1'. Probably out of disk space
2019-06-28T02:13:36.594288Z 1 [ERROR] [MY-012926] [InnoDB] InnoDB: Unable to create the shared innodb_temporary.
2019-06-28T02:13:36.595199Z 1 [ERROR] [MY-012930] [InnoDB] InnoDB: Plugin initialization aborted with error Generic error.
2019-06-28T02:13:36.920373Z 1 [ERROR] [MY-010334] [Server] Failed to initialize DD Storage Engine
2019-06-28T02:13:36.922010Z 0 [ERROR] [MY-010020] [Server] Data Dictionary initialization failed.
2019-06-28T02:13:36.923001Z 0 [ERROR] [MY-010119] [Server] Aborting
2019-06-28T02:13:36.925814Z 0 [System] [MY-010910] [Server] C:¥Program Files¥MySQL¥MySQL Server 8.0¥bin¥mysqld.exe: Shutdown complete (mysqld 8.0.11)  MySQL Community Server - GPL.

ディスク容量が足りないと。どのドライブも十分空きがあるようにみえ、どこが足りないのか?ファイル名が.¥ibtmp1ですがカレントディレクトリが不明で、MySQLが落ちると消えてしまうファイルのようで、場所の特定が難しい。

ならばと一時回避的にE:ドライブを切って、サーバー設定でibtmpを明示的に指定、

innodb_temp_data_file_path = E:/temp/ibtmp1:12M:autoextend:max:5G

これで一応起動。しかしEドライブは一時しのぎなので、作成先をデータディレクトリに変更、

innodb_temp_data_file_path = C:/ProgramData/MySQL/MySQL Server 8.0/Data/ibtmp1:12M:autoextend:max:5G

これも動いたので、とりあえず様子見。う~ん、ドライブ空きが足りないってどこなんだろう…

[2019/6/29 追記] 続きLink

— posted by mu at 12:20 pm   commentComment [0]  pingTrackBack [0]

キルミーベイベーイベント

昨朝e+から何気なくメール通知、昼過ぎに見て慌てて購入、夕方見たら売り切れてた、あぶないあぶない。てか昼過ぎでよく買えたもんだ。殺し屋祭り同様、私はキルミーに関してはチケット運がいい(^_^)V

BDBOXLink 持っていったらカヅホ神のサインいただけるらしい。忘れるわけにはいかない…

— posted by mu at 02:49 pm   commentComment [0]  pingTrackBack [0]

T: Y: ALL: Online:
ThemeSwitch
  • Basic
Created in 0.0210 sec.
prev
2022.8
next
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31