掲示板お問い合わせランダムジャンプ



この広告は30日以上更新がないブログに表示されております。 新しい記事を書くことで広告を消すことができます。

Top Index

2014年06月22日
[WPF]ComboBoxのAutoComplete機能を添付プロパティで実装する
※2014/6/29追記
全角文字(IME変換)に対応していない問題を修正。

このエントリーをはてなブックマークに追加



背景


ComboBoxは単純なようで奥が深いのか、使いづらい。
Binding方法がSelectedValueと、SelectedItemの2つあるのがややこしい。

問題点の掘り下げ


SelectedValueとSelectedItemの特徴を列挙。
(だいたいあっているはず。間違ってたらすいません。)

まずは「SelectedValue」
・Integer、SelectedValueなどのリテラル型のBindingに向く
・ObjectのBingindには向かない
・Nothingの代入はできない
・ItemsSourceに存在しない場合、表示されない

次に「SelectedItem」
・ObjectのBingindに向く
・Nothingの代入はできない
・ItemsSourceに存在しない場合、表示されない
・だいたいの場合、IEquatableインターフェイスを実装して等価判定を行う必要あり


現状での回避策?


・Nothingの代入ができない
IsEditableにして、テキストを編集可能にしてやると解決。
文字列をすべて削除すればNothingになる。
ただし、ItemsSourceに存在しない値も指定できるようになってしまう。
(実際はItemsSourceに存在しなければNothingが代入されるのですが、画面上は入力した文字列が残るため、VMとVで情報の乖離が起きている。)

・ItemsSourceに存在しない場合、表示されない
VM側の値は存在しているが、表現できないので空欄になってるだけ。(VMとVで情報が乖離)
これはTextに現在値をOneWayでBindingすれば、VMとVの乖離が解消される。(OneWayがみそ)

しっくりこないからしっくりさせる


IsEditable=Trueを前提として、以下の点をしっくりさせる。

・Nothingも代入したい
Nothingを許容するかどうかは保存ボタンでやればいいから、ComboBoxoの範疇ではないとする。

・ItemsSourceに存在しない値は選択できない
いわゆるDropDownStyle。
ItemsSourceに存在しない値を指定された場合、Nothingにする。
もちろん、Textに残った残骸文字列もきれいにする。

・でも初期値ならいい
ややこしいので、デモGifで説明しますと、「Group z」というのはItemsSourceには存在しません。
でも、VM側で「Group z」を指定されてしまいました。
こういう場合に限り、ItemsSourceになくてもNothing化はしません。
ただし、一度でも値を変えると二度と「Group z」に戻すことはできません。

・選択候補を絞る
いわゆるオートコンプリート。
本題ではないのだけれど、IsEditableにしてしまったらまぁいるでしょうね。

・選択候補が1つの時にロストフォーカスしたら採用する
本題とずれてきてましたが、便利そうなのでそうします。

ソースコード(添付プロパティ以外)


要点だけピッキング。完全なものはダウンロードファイル参照。



ソースコード(添付プロパティ)


※添付プロパティのソースコード(完全)は長いからページの後半に付けてます。

続きを読む ...
 
[ 投稿者:mk3008 at 17:08 | WPF | コメント(0) | トラックバック(0) ]

2014年05月04日
クリック時にロストフォーカスする添付プロパティ
VS2010+WPF+.NET4

ボタン、チェックボックスをクリックするとフォーカスが移ります。
このあとにスペースキーを押下すると再度クリックイベントが発生します。
これはWindows標準の仕様ですので、なんら問題ないですが、
スペースキーにショートカットキーを割り当てた場合、
上述の使用と競合するため意図しない挙動が起きてしまします。

というわけで、クリックイベント後、強制的にロストフォーカスするプロパティを作る。


添付プロパティめっちゃ便利…
※初期掲載時はビヘイビアとごっちゃになってました。

※フォーカスが移らない場合があったため、ウインドウにフォーカスを映すように変更。
[ 投稿者:mk3008 at 12:58 | WPF | コメント(0) | トラックバック(0) ]

2014年04月06日
ファイルをドロップしてパスを取得する(WPF+MVVM)
filedrop

VS2010+.NET4


参考:KatsuYuzuのブログ - ファイルのドラッグ&ドロップをビヘイビアーで。
http://katsuyuzu.hatenablog.jp/entry/20111219/1324313500

このサイトに解説付きで載ってます。
大変参考になりました。
んで改造してこんな感じにしてみました。

続きを読む ...
 
[ 投稿者:mk3008 at 15:29 | WPF | コメント(0) | トラックバック(0) ]

2014年03月16日
Officeを模したWPFスタイルサンプル(続)
VS2010+WPF+.NET4

こそっと改良。
・Officeの全配色移植
・ハイライト用配色5種(青、赤、黄、緑、灰)
・ボタンスタイル3種(フロート、フラット、透明)
・トグルボタンスタイルも同様に3種
・データグリッドスタイル1種(フラット)
・Background属性に任意の値を指定可能。
 ボーダーや、背景色はBackground属性値から動的に算出。

new theme

3/29追記
こっそりグレースケールが正しく計算されない不具合を修正。

続きを読む ...
 
[ 投稿者:mk3008 at 11:30 | WPF | コメント(0) | トラックバック(0) ]

2014年03月08日
Officeを模したWPFスタイルサンプル
プログラマにデザインセンスは無い…
かどうかは知りませんが、私にはないので、Office(Excel2010)のデザインをWPFに移植しました。
DataGridのデザインも移植してますので、結構いい感じです。

※Officeには配色が20ぐらいあるんですが、全部移植するのは大変なので、5個程度しかやってません。

※行ヘッダーの背景色も変更できましたが、全選択ボタン(左上のボタン)だけが標準のデザインなままなのはどうかと思ったので、そのままにしておきました。


スタイルを適用したサンプルは続きをご覧ください。(画像でかめ)

スタイルの切り替え方:
動的に切り替えることはできませんので、「/ResourceDictionaries/Theme.xaml」を開いて、3〜5行目にあるMergedDictionariesを適用したいスタイルに変更すればOK。
具体的には

<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ResourceDictionaries/ColorSchemes/Office.xaml" />
</ResourceDictionary.MergedDictionaries>



<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ResourceDictionaries/ColorSchemes/Executive.xaml" />
</ResourceDictionary.MergedDictionaries>

こんな感じに変更するだけ。
あとはMainWIndows.xamlを見て使い方を察してください。

参考:
・DataGridTemplateSample
このソースコードを相当参考にしていますが、元ネタのサイトを失念。大変助かりました。
WPF Toolkit DataGrid Sample 06 - Styling the SelectAllRows button
参考にはしていませんが、SelectAllButtonもカスタムできるみたいですね!

続きを読む ...
 
[ 投稿者:mk3008 at 21:03 | WPF | コメント(0) | トラックバック(1) ]

2011年10月30日
ReadOnly時、TextBoxになるComboBox
VisualStudio2010、WPF、VB2010、.NET4
※注意:TextBox表示としていますが、Labelでもなんでもいいです。個人的に文字列選択はしたいのでTextBoxにしただけです。深い意味はありません。


※2011/11/3 VMへ書き戻しされない不具合を修正。

ComboBoxのReadOnlyプロパティにしても、なぜか編集をロックすることができません。(できるかもしれませんが、見た目はどうみても編集できそう)
ですので、通常であればIsEnabledプロパティを使って編集をロックすると思いますが、IsEnabledだとグレーアウトしてしまう関係上、文字が見づらい・・・

ならば、ControlTempalteを使ってコントロールをごっそり入れ替えてしまいましょう。
完成後の画像:ReadOnly=False
ReadOnlyFalse

完成後の画像:ReadOnly=True
ReadOnlyTrue

以下、ポイントとか。

続きを読む ...
 
[ 投稿者:mk3008 at 15:22 | WPF | コメント(2) | トラックバック(1) ]

2011年06月04日
アイコンのグレーアウト方法(メモ)
アイコンのグレーアウト方法について、参考になるサイトがあったのでメモ。

以下メモ書き。

Image(画像、イメージ、アイコン)がDisabled(IsEnabled=False)のとき、グレースケール(モノクロ、グレーアウト)化する方法のリンク。

[WPF] How to gray the icon of a MenuItem ?
http://weblogs.asp.net/thomaslebrun/archive/2009/03/03/wpf-how-to-gray-the-icon-of-a-menuitem.aspx


Imageクラスを継承して、AutoGreyableImageクラスを作成。
AutoGreyableImageクラス内でIsEnabledプロパティをオーバーライド?
・・・動作確認してないので、よくわかりませんが使い方がImageクラスと変わらないのでよさげ。

できれば自作せずに標準でそうなって欲しいところですが。
[ 投稿者:mk3008 at 12:17 | WPF | コメント(0) | トラックバック(0) ]

「WPFで透明なボタン」にWin7風のアニメーションを付けてみる
元ネタはこちら
WPFで透明なボタン
http://social.msdn.microsoft.com/Forums/ja-JP/csharpgeneralja/thread/a901b7ed-d829-414c-a9a1-a7392629e81f/


私も投稿者と同じようなことをしたかったので、こちらの記事は大変参考になりました。
ただ、こちらの記事は「透明なボタン」のサンプルなので、アニメーションはなく、フォーカス感やクリック感などはありません。
というわけで、Windows7の配色を元に、マウスオーバー時、プレス時のアニメーションを追加してみました。

※トグルボタンのスタイルもおまけで作成

続きを読む ...
 
[ 投稿者:mk3008 at 11:55 | WPF | コメント(0) | トラックバック(0) ]

2011年05月19日
ドロップダウンボタンを作る
DropDownButton

<ToolBar DockPanel.Dock="Top">

    <Menu VerticalAlignment="Center" Background="Transparent" Margin="0,-1,0,0" >
        <MenuItem>
            <MenuItem.Header>
                <StackPanel Orientation="Horizontal" >
                    <Label VerticalContentAlignment="Center" Content="DropDownButton" Padding="0,0,3,0" />
                    <Label VerticalContentAlignment="Center" Padding="0" >
                        <Polygon Points="0,0 6,0 3,3" Fill="Black" Stroke="Black" StrokeThickness="0.5" />
                    </Label>
                </StackPanel>
            </MenuItem.Header>
            <MenuItem Header="Inner Menu Item 1"  VerticalAlignment="Center" />
            <MenuItem Header="Inner Menu Item 2"  VerticalAlignment="Center" />
            <MenuItem Header="Inner Menu Item 3"  VerticalAlignment="Center" />
        </MenuItem>
    </Menu>

</ToolBar>
ポイント
  • ドロップダウンボタンの挙動はMenuItemとほぼ同じなので、MenuItemで代用する。
  • MenuItemはMenuの中に入っていないとドロップダウンしないので、Menuがコンテナとして必要。
  • Menu、MenuItemは背景が微妙(ボタンとも違うグラデーションでミスマッチ)なので、透明化して、ごまかす。
  • Menuコントロールないのアイテムは微妙に縦方向にマージンが入り、文字の位置が通常のコントロールとずれたりする。
    サンプルでは上方向のマージンを -1 してごまかしてます。
    試してはいませんが、Menuのコンテナのテンプレートを弄って、マージンを入らないようにするとすっきりするかもしれない。
  • ToolBarの中にセットすると違和感ないですが、ToolBarの外、たとえばGridとかに配置すると、デザイン的に違和感ありまくり。
  • SplitButtonもなんとかして作りたいものです。
スタイル化すると、こんな感じ。

<Style TargetType="{x:Type MenuItem}" x:Key="DropDownMenuItemStyle" >
    <Setter Property="HeaderTemplate">
        <Setter.Value>
            <DataTemplate >
                <StackPanel Orientation="Horizontal" Margin="0,-1,0,0">
                    <Label VerticalContentAlignment="Center" 
                           Content="{Binding Header, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MenuItem}}}"
                           Padding="0,0,3,0" />
                    <Label VerticalContentAlignment="Center" Padding="0" >
                        <Polygon Points="0,0 6,0 3,3" Fill="Black" Stroke="Black" StrokeThickness="0.5" />
                    </Label>
                </StackPanel>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

[ 投稿者:mk3008 at 22:09 | WPF | コメント(0) | トラックバック(0) ]

2011年05月07日
択一しかできないトグルボタンを作る

<!--トグルラジオボタン -->
<Style TargetType="{x:Type RadioButton}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type RadioButton}">
                <ToggleButton IsChecked="{Binding IsChecked, Mode=Twoway, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type RadioButton}}}"
                              IsEnabled="{TemplateBinding IsEnabled}"
                              Focusable="False">
                    <ContentPresenter DataContext="{TemplateBinding DataContext}" />
                </ToggleButton>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

ポイント
  • 択一の動作をするコントロール「ラジオボタン」の外見をトグルボタンに変えることで対応する。
  • ラジオボタンのデータコンテンツを利用できるよう、TemplateBindingする。
  • ラジオボタンのチェックステータスをトグルボタンとバインディングする。
    このとき、TemplateBindingではなく、Bindingを使用すること。
    理由:TemplateBindingだと、バインディングモードがTwowayにならないので、ラジオボタンのIsCheckedプロパティが更新されても、トグルボタンのIsCheckedプロパティに反映されない。
  • トグルボタンのFocusableプロパティをFalseにしておくこと。
    理由:トグルボタンはフォーカスがないときにIsCheckedプロパティを更新すると、トグルボタンの周りがなぜかハイライトされるため。
    動作上の問題はありませんが、見た目が変になるのでFalseにしておいたほうが吉。
[ 投稿者:mk3008 at 21:45 | WPF | コメント(0) | トラックバック(0) ]