Styleの適用方法色々メモ
自分の以下の対象ターゲットのプロパティを固定する
青い四角のスタイルを設定する。
<Grid> <Grid.Resources> <Style TargetType="Rectangle"> <Setter Property="Fill" Value="Blue"/> </Style> </Grid.Resources> <Rectangle Height="10" Width="10" /> </Grid>
キー名をつけてそれぞれのスタイルを指定する。
<Grid> <Grid.Resources> <Style x:Key="sty1" TargetType="Rectangle"> <Setter Property="Fill" Value="Blue"/> </Style> <Style x:Key="sty2" TargetType="Rectangle"> <Setter Property="Fill" Value="Red"/> </Style> </Grid.Resources> <StackPanel> <Rectangle Height="10" Width="10" Style="{StaticResource sty1}"/> <Rectangle Height="10" Width="10" Style="{StaticResource sty2}"/> </StackPanel> </Grid>
Style.Triggerでのスタイル適用
プロパティの設定値によって、スタイルの変更を指定する。
<Grid.Resources> <Style TargetType="TextBox"> <Style.Triggers> <Trigger Property="IsEnabled" Value="True"> <Setter Property="Background" Value="White"/> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter Property="Background" Value="Silver"/> </Trigger> </Style.Triggers> </Style> </Grid.Resources>
.NetでBarcodeを作成し、印刷まで
目標
フリーパッケージでバーコードを作成し、印刷する。
有料パッケージだと色々便利だが、以前からAccessやExcelに組み込まれたバーコードコントロールを使っているお客様には、金を使う気が無いので、却下になっている。
Nugetからパッケージをインストールする。
「barcode」で検索すると色々な候補が出てくるが、ほとんど有料だった。(IronBarcode, Spireなどなど)
結果、「Zen Barcode Rendering Framework」を使う。
種類に制約があるが、今回は問題なし
PM> Install-Package Zen.Barcode.Rendering.Framework -Version 3.1.10729.1
Nuget:
https://www.nuget.org/packages/Zen.Barcode.Rendering.Framework/
GitHub:
https://github.com/dementeddevil/BarcodeRenderingFramework
使い方
基本生成したバーコードをImage形式に保存する。
そのときに使うBarcodeDrawFactoryを切替ることで、生成されるバーコードも変わる仕組みらしい
using Zen.Barcode; private Code128BarcodeDraw _barcode; private Image _img; public void CreateBarcode(string barcodeText, int barHeight = 50, int scale = 2) { _barcode = BarcodeDrawFactory.Code128WithChecksum; _img = _barcode.Draw(barcode_text, barHeight, scale); }
scaleはデフォルトだと少し小さめだったため、2にしてみた。
印刷用に編集
出来上がったバーコードはまさにバーコードのみだったため、印刷用イメージを作成する。
こんな感じにしたい
//背景イメージ作成(バーコードイメージの余白になるように大きめにする。) System.Drawing.Image backImg = new Bitmap(img.Width + 20, img.Height + 40, System.Drawing.Imaging.PixelFormat.Format32bppArgb); Graphics g = Graphics.FromImage(backImg); Brush b = new SolidBrush(Color.Black); Font f = new Font("Courier", 13); StringFormat sf = new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Far }; //背景クリア g.Clear(Color.White); g.DrawImage(img, 10, 10); //バーコードを貼り付け g.DrawString(bm.BarcodeText, f, b, backImg.Width / 2, backImg.Height, sf); //バーコード文字を下部に配置 this.picBox.Image = backImg;
印刷
印刷もやり方探すのにかなり苦労したけど、最終的に作ったイメージを印刷で落ち着いた
//PrintDocumentを初期化し、プリントイベントを紐付ける。 var pd = new System.Drawing.Printing.PrintDocument(); pd.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this.pd_PrintPage); pd.Print(); pd.PrintPage -= this.pd_PrintPage; //PrintDocument.Print();により、以下が実行される。 private void pd_PrintPage(Object sender, System.Drawing.Printing.PrintPageEventArgs e) { //ImageをeのGraphicsに当てたら、印刷された。 e.Graphics.DrawImage(_img, 0, 0); }
.NETでAccessをDBとして使う
必要になった理由
バッチでAccessのDBを読み取りSql Serverに更新するような要望が発生したため
Àccess DBを.NETで読み取る
以前のAccess2003(.mdb)の場合、「Microsoft.Jet.OLEDB.4.0」を使うらしいが、Access2010(.accdb)以降は、「Microsoft.ACE.OLEDB.12.0」をプロバイダとして使用するらしい
Microsoft Access Database Engine 2016インストール
以下のリンクからダウンロードした。
Download Microsoft Access Database Engine 2016 Redistributable from Official Microsoft Download Center
32bitバント64bit版があるが、64bitのOSには32bit版はインストール時エラーになった。
トラブル
「Microsoft.ACE.OLEDB.12.0' プロバイダーはローカルのコンピューターに登録されていません。」
とエラーになるばかり、いろいろ調べて見ると、AniCpuやx64ではうまく動かず、実行時探しているバージョンは32bitだそう。
仕方ないので、64bit版は削除し、32bit版をインストールする。
AccessDatabaseEngine.exe /quiet
※64bit版OSでは「/quite」オプションで強制的にインストールが可能
一旦、これで接続は成功した。
ソース
プラットフォームはx86で作業しています。
using System.Data; using System.Data.OleDb; private const string CONNECTION_STRING = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\db\myDb.accdb"; private OleDbConnection _conn; public void ExecuteSql() { _conn = new OleDbConnection(CONNECTION_STRING); _conn.Open(); OleDbCommand cmd =_conn.CreateCommand(); cmd.CommandText = "SELECT * FROM MY_TABLE"; DataTable dt; OleDbDataAdapter oda = new OleDbDataAdapter(cmd) oda.Fill(dt) _conn.Close(); }
パスワードがついているAccessの場合
「Jet OLEDB:Database Password」でパスワードを指定する
private const string CONNECTION_STRING = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\db\myDb.accdb;Jet OLEDB:Database Password=abc";
読取り専用モードでAccessを開きたい場合
「Mode」を指定してAccessを開く
指定値毎のモード
No | Mode |
---|---|
Mode=1 | Read |
Mode=2 | Share Deny None |
Mode=3 | ReadWrite |
Mode=4 | Share Deny None |
Mode=5 | Share Deny None |
Mode=6 | Share Deny None |
Mode=7 | Share Deny None |
Mode=8 | Share Deny Write |
Mode=9 | Share Deny None |
Mode=10 | Share Deny None |
Mode=11 | Share Deny None |
Mode=12 | Share Deny Read|Share Deny Write |
Mode=13 | Read|Share Deny Read|Share Deny Write |
Mode=14 | Share Deny None |
Mode=15 | Share Deny None |
Mode=16 | Share Deny None |
Mode=17 | Share Deny None |
Mode=18 | Share Deny None |
Mode=19 | ReadWrite|Share Deny None |
private const string CONNECTION_STRING = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\db\myDb.accdb;Mode=1";
ToggleButtonカスタマイズ
ToggleButtonを実装してみたものの、ControlTemplateが上手く動かなかったので、最終的に成功したパターンをメモ
と言っても、結局はStyleのTriggerで定義するだけでも解決だった
<ToggleButton x:Class="CustomToggleButton" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:App1" mc:Ignorable="d" > <ToggleButton.Style> <Style TargetType="ToggleButton" BasedOn="{StaticResource {x:Type ToggleButton}}"> <Setter Property="Background" Value="White" /> <Setter Property="Foreground" Value="Red" /> <Setter Property="BorderBrush" Value="Red" /> <Setter Property="BorderThickness" Value="2" /> <Setter Property="FontWeight" Value="Bold" /> <Setter Property="HorizontalContentAlignment" Value="Center" /> <Setter Property="VerticalContentAlignment" Value="Center" /> <Style.Triggers> <Trigger Property="IsChecked" Value="True"> <Setter Property="Background" Value="Red"/> <Setter Property="Foreground" Value="White"/> </Trigger> <Trigger Property="IsChecked" Value="False"> <Setter Property="Background" Value="White"/> <Setter Property="Foreground" Value="Red"/> </Trigger> </Style.Triggers> </Style> </ToggleButton.Style> <ToggleButton.Template> <ControlTemplate TargetType="{x:Type ToggleButton}"> <Grid x:Name="MyButton" Background="Transparent"> <Border x:Name="MyBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="5" Background="{TemplateBinding Background}"/> <ContentPresenter x:Name="Presenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /> </Grid> </ControlTemplate> </ToggleButton.Template> </ToggleButton>
既存ボタンのスタイルを継承しながら、カスタムボタン作成
ボタンとスタイルを定義
※StyleにBasedOnを指定しないと、既存のスタイルした表示してくれなかったので注意
<Button x:Class="CustomButton" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:App1" mc:Ignorable="d" > <Button.Style> <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}"> <Setter Property="Background" Value="White" /> <Setter Property="Foreground" Value="#E50012" /> <Setter Property="BorderBrush" Value="#E50012" /> <Setter Property="BorderThickness" Value="2" /> <Setter Property="FontWeight" Value="Bold" /> <Setter Property="HorizontalContentAlignment" Value="Center" /> <Setter Property="VerticalContentAlignment" Value="Center" /> </Style> </Button.Style>
ControlTemplateを設定する。
今回はVisualStateManagerを使いVisualState単位で状態を変更する。 Storyboardは基本アニメーション効果があるため、時間やFrom・Toの指定で変更効果を表示することが可能
<Button.Template> <ControlTemplate TargetType="{x:Type Button}"> <!--ボタンは基本四角い状態であるため、せっかく丸いBorderにしてもはみ出て角が見えていたため透明にした--> <Grid x:Name="MenuButton" Background="Transparent"> <!--ボタンの枠線:CornerRadiusで丸みを設定できる。--> <Border x:Name="MenuBorder" BorderBrush="#E50012" BorderThickness="3" CornerRadius="10" Background="{TemplateBinding Background}"/> <!--ボタン内の本体?--> <ContentPresenter x:Name="Presenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /> <VisualStateManager.VisualStateGroups> <VisualStateGroup Name="CommonStates"> <VisualState Name="Normal" /> <VisualState Name="MouseOver"> <Storyboard> <ColorAnimation Storyboard.TargetName="MenuBorder" Storyboard.TargetProperty="Background.(SolidColorBrush.Color)" Duration="00:00:00.1" To="LightPink" /> <ColorAnimation Storyboard.TargetName="Presenter" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Duration="00:00:00.1" To="#E50012" /> </Storyboard> </VisualState> <VisualState Name="Pressed"> <Storyboard> <ColorAnimation Storyboard.TargetName="MenuBorder" Storyboard.TargetProperty="Background.(SolidColorBrush.Color)" Duration="00:00:00.1" To="#E50012" /> <ColorAnimation Storyboard.TargetName="Presenter" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Duration="00:00:00.1" To="white" /> <ThicknessAnimation Storyboard.TargetName="MenuBorder" Storyboard.TargetProperty="Margin" Duration="00:00:00.1" To="0,0,0,0" /> </Storyboard> </VisualState> <VisualState Name="Disabled"> <Storyboard> <ColorAnimation Storyboard.TargetName="MenuBorder" Storyboard.TargetProperty="BorderBrush.(SolidColorBrush.Color)" To="Gray"/> <ColorAnimation Storyboard.TargetName="Presenter" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" To="Gray"/> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> </Grid> </ControlTemplate> </Button.Template>
VisualState関連参考
以下のリンクから、全コントロール分のスタイルテンプレートを参照可能 コントロールのスタイルとテンプレート | Microsoft Docs