[ カテゴリー » PC関連 ]

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]

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]

GeForce RTX系のドライバがWindows Server 2016に入らない

20190213-GeForceDriverInstallFailedOnWinSvr2016_3

Windows ServerでGeForceを使うときはWindows desktop用ドライバを使うというのが常なのですが、先日入手した2080Tiのドライバをインストールしようとすると、失敗しましただけの無慈悲な表示。インストーラの実態は自己解凍形式のZIPなので解凍して、デバイスマネージャーからINFファイル指定で入れようとすると、'The driver selected for this device does not support this version of Windows'、つまりこのWindowsはサポートしませんと。

ついにGeForceをWindows Serverに入れる道を塞がれたかと思ったのですが、どうやらServer/Desktopの違いではなくバージョン1803以上のWindowsが必要らしい。Windows Server 2016のWindowsバージョンは1607、古いんですね。1803以上という条件を満たすWindows Serverは2019。評価版2019で試したところWindows 10用ドライバが入り、2080Tiが認識されました。

GeForceはWindows desktop用、サポート期限が過ぎたWindowsはドライバも対応しませんよということらしい。サポート期限が18か月しかないWindows 10のペースに合わせていると、新しいGPU買うとWindows Serverも上げないといけないという事態になりそうです。Quadro買えばWindows Serverのライフタイム(今なら2008 R2まで)ドライバが提供されるようですが、Quadroは高いし、う~ん…

— posted by mu at 05:42 pm   commentComment [0]  pingTrackBack [0]

Visual Studio 2015をWindows 10にインストールしたら

20190109-VS2015_SignInFail

サインイン時にこのエラー(Object doesn't support property or method 'startWith')。Webページのスクリプト処理中に出しているようなのでもしやと思い、既定のブラウザをEdgeからFirefoxにしたら解決。

自社製品でこういうこと起こすの、やめ~や…

[2018/01/10 追記] そういえばWindows Server 2016では問題起きてなかった。あちらの規定ブラウザはIE11なので、IEなら大丈夫なのだろう。

— posted by mu at 05:46 pm   commentComment [0]  pingTrackBack [0]

T: Y: ALL: Online:
ThemeSwitch
  • Basic
Created in 0.0256 sec.
prev
2024.4
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