[ カテゴリー » PC関連 ]

WPF TreeViewのアイテムを幅一杯に伸ばす

blog20130222-StretchTreeViewItem

TreeViewLink の各アイテムを枠囲みしたり背景を色付にしようとすると、内部のテキストをぴったり納めるような枠のサイズになってデコボコしたりLink中身のサイズを固定するとサブアイテムのお尻が右に飛び出るLink といまいち綺麗じゃありません。

TreeView.HorizontalContentAlignment=Stretchで解決できると思いきや、TreeViewはこのプロパティを華麗に無視。TreeViewItemのテンプレートを根こそぎ変更しないといけないらしい。1から書くと大変そうなのでネットにあったテンプレートLink を改造。変更点は、

  • テンプレートの最初にあるGridがTreeViewItemを表示する部分。HorizontalAlignment="Stretch"にして目一杯横に広がるようにする。
  • そのGridの2カラム目が肝心の中身。ここのWidthをAutoから*に。
  • 3カラム目は要らない子なので削除。
  • 消した3カラム目の辻褄合わせに、下のほうにあるItemsPresenterのColumnSpan指定を削除。
<UserControl x:Class="TreeViewTest"
             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"
             mc:Ignorable="d" 
             d:DesignHeight="100" d:DesignWidth="300">

    <UserControl.Resources>
        <Style TargetType="TreeViewItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="TreeViewItem" xmlns:s="clr-namespace:System;assembly=mscorlib">
                        <Grid HorizontalAlignment="Stretch">
                        <!--
                        <Grid>
                        -->
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" MinWidth="19" />
                                <ColumnDefinition Width="*"/>
                                <!-- Change to expand width of tree items to base TreeView size (expand to right edge)
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="*" />
                                -->
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition />
                            </Grid.RowDefinitions>
                            <ToggleButton IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent},Path=IsExpanded,Mode=TwoWay}" ClickMode="Press" Name="Expander">
                                <ToggleButton.Style>
                                    <Style TargetType="ToggleButton">
                                        <Style.Resources>
                                            <ResourceDictionary />
                                        </Style.Resources>
                                        <Setter Property="UIElement.Focusable">
                                            <Setter.Value>
                                                <s:Boolean>False</s:Boolean>
                                            </Setter.Value>
                                        </Setter>
                                        <Setter Property="FrameworkElement.Width">
                                            <Setter.Value>
                                                <s:Double>16</s:Double>
                                            </Setter.Value>
                                        </Setter>
                                        <Setter Property="FrameworkElement.Height">
                                            <Setter.Value>
                                                <s:Double>16</s:Double>
                                            </Setter.Value>
                                        </Setter>
                                        <Setter Property="Control.Template">
                                            <Setter.Value>
                                                <ControlTemplate TargetType="ToggleButton">
                                                    <Border Padding="5,5,5,5" Background="#00FFFFFF" Width="30" Height="30">
                                                        <Path Fill="#00FFFFFF" Stroke="#FF989898" Name="ExpandPath">
                                                            <Path.Data>
                                                                <!--※②マークを変えるにはここの値を変える-->
                                                                <PathGeometry Figures="M0,0L0,10L10,0z" />
                                                            </Path.Data>
                                                            <Path.RenderTransform>
                                                                <RotateTransform Angle="135" CenterX="3" CenterY="3" />
                                                            </Path.RenderTransform>
                                                        </Path>
                                                    </Border>
                                                    <ControlTemplate.Triggers>
                                                        <Trigger Property="UIElement.IsMouseOver">
                                                            <Setter TargetName="ExpandPath" Property="Shape.Stroke">
                                                                <Setter.Value>
                                                                    <SolidColorBrush>#FF1BBBFA</SolidColorBrush>
                                                                </Setter.Value>
                                                            </Setter>
                                                            <Setter TargetName="ExpandPath" Property="Shape.Fill">
                                                                <Setter.Value>
                                                                    <SolidColorBrush>#00FFFFFF</SolidColorBrush>
                                                                </Setter.Value>
                                                            </Setter>
                                                            <Trigger.Value>
                                                                <s:Boolean>True</s:Boolean>
                                                            </Trigger.Value>
                                                        </Trigger>
                                                        <Trigger Property="ToggleButton.IsChecked">
                                                            <Setter TargetName="ExpandPath" Property="UIElement.RenderTransform">
                                                                <Setter.Value>
                                                                    <RotateTransform Angle="180" CenterX="3" CenterY="3" />
                                                                </Setter.Value>
                                                            </Setter>
                                                            <Setter TargetName="ExpandPath" Property="Shape.Fill">
                                                                <Setter.Value>
                                                                    <SolidColorBrush>#FF595959</SolidColorBrush>
                                                                </Setter.Value>
                                                            </Setter>
                                                            <Setter TargetName="ExpandPath" Property="Shape.Stroke">
                                                                <Setter.Value>
                                                                    <SolidColorBrush>#FF262626</SolidColorBrush>
                                                                </Setter.Value>
                                                            </Setter>
                                                            <Trigger.Value>
                                                                <s:Boolean>True</s:Boolean>
                                                            </Trigger.Value>
                                                        </Trigger>
                                                    </ControlTemplate.Triggers>
                                                </ControlTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </Style>
                                </ToggleButton.Style>
                            </ToggleButton>
                            <Border BorderThickness="{TemplateBinding Border.BorderThickness}" Padding="{TemplateBinding Control.Padding}" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" Name="Bd" SnapsToDevicePixels="True" Grid.Column="1">
                                <ContentPresenter Content="{TemplateBinding HeaderedContentControl.Header}" ContentTemplate="{TemplateBinding HeaderedContentControl.HeaderTemplate}" ContentStringFormat="{TemplateBinding HeaderedItemsControl.HeaderStringFormat}" ContentSource="Header" Name="PART_Header" HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
                            </Border>
                            <!--
                            <ItemsPresenter Name="ItemsHost" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="2"/>
                            -->
                            <ItemsPresenter Name="ItemsHost" Grid.Column="1" Grid.Row="1"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="TreeViewItem.IsExpanded">
                                <Setter TargetName="ItemsHost" Property="UIElement.Visibility" Value="{x:Static Visibility.Collapsed}" />
                                <Trigger.Value>
                                    <s:Boolean>False</s:Boolean>
                                </Trigger.Value>
                            </Trigger>
                            <Trigger Property="ItemsControl.HasItems">
                                <Setter TargetName="Expander" Property="UIElement.Visibility" Value="{x:Static Visibility.Hidden}" />
                                <Trigger.Value>
                                    <s:Boolean>False</s:Boolean>
                                </Trigger.Value>
                            </Trigger>
                            <Trigger Property="TreeViewItem.IsSelected">
                                <Setter TargetName="Bd" Property="Panel.Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
                                <Setter Property="TextElement.Foreground">
                                    <Setter.Value>
                                        <DynamicResource ResourceKey="{x:Static SystemColors.HighlightTextBrushKey}" />
                                    </Setter.Value>
                                </Setter>
                                <Trigger.Value>
                                    <s:Boolean>True</s:Boolean>
                                </Trigger.Value>
                            </Trigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="TreeViewItem.IsSelected">
                                        <Condition.Value>
                                            <s:Boolean>True</s:Boolean>
                                        </Condition.Value>
                                    </Condition>
                                    <Condition Property="Selector.IsSelectionActive">
                                        <Condition.Value>
                                            <s:Boolean>False</s:Boolean>
                                        </Condition.Value>
                                    </Condition>
                                </MultiTrigger.Conditions>
                                <Setter TargetName="Bd" Property="Panel.Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
                                <Setter Property="TextElement.Foreground">
                                    <Setter.Value>
                                        <DynamicResource ResourceKey="{x:Static SystemColors.ControlTextBrushKey}" />
                                    </Setter.Value>
                                </Setter>
                            </MultiTrigger>
                            <Trigger Property="UIElement.IsEnabled">
                                <Setter Property="TextElement.Foreground">
                                    <Setter.Value>
                                        <DynamicResource ResourceKey="{x:Static SystemColors.GrayTextBrushKey}" />
                                    </Setter.Value>
                                </Setter>
                                <Trigger.Value>
                                    <s:Boolean>False</s:Boolean>
                                </Trigger.Value>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>

            <Setter Property="ItemsPanel">
                <Setter.Value>
                    <ItemsPanelTemplate>
                        <!--※①マージンを変える場合はここ-->
                        <StackPanel IsItemsHost="True" Margin="20,0,0,0"/>
                    </ItemsPanelTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>

    <TreeView Name="tree" ItemsSource="{Binding Items}" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate DataType="{x:Type TVItem}" ItemsSource="{Binding Items}">
                <Border BorderBrush="Silver" BorderThickness="2" Margin="0.5" Padding="2">
                    <Grid HorizontalAlignment="Stretch">
                        <Grid.RowDefinitions>
                            <RowDefinition MinHeight="32"/>
                            <RowDefinition MinHeight="20"/>
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="200"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Content="{Binding Name}" FontSize="20" HorizontalAlignment="Left" VerticalAlignment="Center" />
                        <Label Grid.Row="1" Grid.Column="0" Content="{Binding Status}" FontSize="16" HorizontalAlignment="Left" VerticalAlignment="Center"/>
                        <ProgressBar Grid.Row="1" Grid.Column="1" Minimum="0" Maximum="1" Value="{Binding Progress}" HorizontalAlignment="Stretch"/>
                    </Grid>
                </Border>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
</UserControl>
元データとなるCLRクラスはこんな感じです。
public partial class TreeViewTest : UserControl
{
    public TreeViewTest()
    {
        InitializeComponent();

        DataContext = new
        {
            Items = new TVItem[]
            {
                new TVItem()
                {
                     Name = "Item 1",
                     Status = "Status 1",
                     Progress = 0.1
                },
                new TVItem()
                {
                    Name = "Item 2",
                    Status = "Status 2",
                    Progress = 0.3,
                    Items = new TVItem[]
                    {
                        new TVItem()
                        {
                            Name = "Item 2-1",
                            Status = "Status 2-1",
                            Progress = 0.5
                        },
                        new TVItem()
                        {
                            Name = "Item 2-2",
                            Status = "Status 2-2",
                            Progress = 0.7
                        }
                    }
                }
            }
        };
    }
}

public class TVItem
{
    public string Name { get; set; }
    public string Status { get; set; }
    public double Progress { get; set; }
    public IEnumerable<TVItem> Items{ get; set; }
}

[参考]

[2013/02/24] コード修正

— posted by mu at 07:03 pm  

DD-WRTでNTPサーバー

1 of 41234Next»
早くも先日購入したRTX-1000Link は引退の方向。理由はVPN機能でして、RTX-1000が提供している2つのVPNは
  • PPTP: 解読されてしまってるLink 。現時点解析に必要なマシンがそれほど安くないので、個人使用のVPNを解読されるリスクを気にしないなら使えますが。
  • IPSec: 通信するマシンのどちらかがグローバル固定IPが必要とのこと。やりたいのは出先からDDNSで運用している自宅への接続なのでこれもダメ。

授業料は安かったとはいえ、もうちょっと事前に調べておけばよかった。次の案として出てきたのがDD-WRTLink 。これは市販の安価なブロードバンドルーターにもよく使われているファームウェアですが、市販品はブラウザを介して限定した機能しかユーザーに変更を許してないため、ファームウェアを書き換えて隠された設定も表に出すというもの。

OpenVPN機能を使うとなるとファームウェアのサイズが大きくなってしまうため、それを格納できるフラッシュメモリ容量が必要になります。となると機種が一挙に限定されまして、Buffalo WZR-HP-G300NH/301NHLink ぐらいでしょうか、入手しやすいのは。

暗号キーをブラウザ経由で設定するというのがなんとも違和感ありますが、OpenVPNも動くようです。となると欲が出て来まして、自宅向けNTPサーバーもこいつに担わせたい。が、これが結構大変。

  • DD-WRT標準のntpd: 返事がない。ただのクライアントのようだ。どうやら自機(ルーター)の内蔵時計を合わせるためだけにあり、サーバー機能を有効にする方法がわからず。
  • いわゆるフル機能ntpd: 実行直後にSegmentation faultが出て落ちる。
  • busybox ntpd: クライアントからの問い合わせが、前回から時間が経っていると失敗することが多い。
  • openntpd: 上位サーバーを選ぶ

次ページより、busybox ntpdとopenntpdの備忘録。

1 of 41234Next»

— posted by mu at 11:13 am   commentComment [0]  pingTrackBack [0]

ヤマハRTX1000購入

blog20130127-RTX1000

往年の名機。本当に企業用ネットワークを扱っている人から見ればこいつは業務用ルーターではなく、SOHO向けISDNダイアルアップルーターってことになるのでしょうか。ただ当時の値段は個人が手を出そうと思うものでなかったのは確か。

それが今や中古で1000円台ですよ、旦那。他機種の価格を見る限り、どうもギガビットイーサを積んでいるかどうかが値段の分かれ目らしい。今まで家のLANでちょっと凝ったことしようとするとルーティングに困っていたこともあり、ネットワークのお勉強のためにとポチった次第。

…さすがだ。ADSL契約でレンタルされた家庭用ルーターなんかとは設定項目数が桁違い。最初どこから手を付けていいのか全く分からず、ネットで設定例Link を見なかったらお手上げ状態でした。現在やっとPPPoE・IPマスカレード・パケットフィルタの設定が完了。次はVPNかなぁ。

実は最も手こずったのは最初のシリアルポート接続だったりする orz
  1. USB-シリアル変換機購入 → オスメスが合わない
  2. ジェンダーチェンジャー購入 → ストレート接続型では☓ってことを知る
  3. クロス接続シリアルケーブル購入 → USB-シリアル変換機がWindowsで認識しなくなった
  4. 変換名人USB-RS232Link をWindows7 x64で使うには古いドライバを使用しないといけない。Windows Updateでドライバを更新したのを忘れており混乱(というか新しいドライバじゃダメということに頭が回らなかった)。
blog20130127-RTX1000CircuitBoard

[2013/1/27 追記] この手の中古を買うと一番心配なのが電解コンデンサーの劣化。私が関わったPCとLANハブ故障原因の半数以上がこれだと思う(あとはHDDとDRAM)。壊れる前に換えておこうかと思い中を開けてみると、100V電源に一番近いコンデンサが耐圧350V、その他のコンデンサはすべてニチコン品。頑丈そうなのでとりあえず下手に手を出すのは止めておきます。


— posted by mu at 10:41 am   commentComment [2] 

XAML - BindingでSrtingFormatが無視される

備忘録。

XAMLでバインディングで得られる値がすでにSystem.Stringの場合(TextBox.Textなど)、変換する必要が無いためStringFormatは無視される。文字列をフォーマットする一つの方法は、IValueConverterLink を実装して、BindingにConverterプロパティを指定する。

[参考]

XAML Binding’s StringFormat Ignored! (Ben Gribaudo)Link

— posted by mu at 02:39 pm  

Nexus7購入

blog20121105-Nexus7

物欲の秋。

動画/Webプレイヤーとしてフィリピン出張前に欲しかったのですが、品薄で手に入らず。出張中に32GB版が発表されたので結果的には良かったのですが、品薄は相変わらずのようで帰国後3軒回って最後の1台を獲得。iPad miniより入手困難ですよとも言われたな。

Googleアカウントすら持ってない状態からのスタート。しばらく遊べそう。

これで目的が達成できない場合、物欲リストにThinkPad Tablet 2Link が…

— posted by mu at 08:39 am  

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