WPFのTreeViewいじってみた。
バインド対象のモデル。
やべ、C#は覚えてるけど、WPFは2年いじってないからほぼ忘れた(;・∀・)
ここ眺めながら必死に思い出す。
class ModelDataValue : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public ModelDataValue(ModelDataValue parent, string path) { if (!Directory.Exists(path)) throw new ArgumentException("path not found :" + path, path); this.info = new DirectoryInfo(path); this.parentNode = parent; this.children = null; } private ModelDataValue parentNode; private DirectoryInfo info; private ReadOnlyCollection<ModelDataValue> children; private bool _isExpanded; private bool _isSelected; public string Name { get { return info.Name; } } public ModelDataValue Parent { get { return this.parentNode; } } public bool IsExpanded { get { return this._isExpanded; } set { if (this._isExpanded == value) return; this._isExpanded = value; this.OnPropertyChanged("IsExpanded"); } } public bool HasNoChildren { get { return this.children == null; } } public bool IsSelected { get { return this._isSelected; } set { if (this._isSelected == value) return; this._isSelected = value; this.OnPropertyChanged("IsSelected"); } } public ReadOnlyCollection<ModelDataValue> Children { get { this.CreateChildren(); return this.children; } } private void CreateChildren() { if (this.HasNoChildren) { List<ModelDataValue> lists = new List<ModelDataValue>(); foreach (var directoryInfo in this.info.GetDirectories()) { lists.Add(new ModelDataValue(this, directoryInfo.FullName)); } this.children = new ReadOnlyCollection<ModelDataValue>(lists); } } private void OnPropertyChanged(string propertyName) { if (this.PropertyChanged != null) { PropertyChangedEventArgs args = new PropertyChangedEventArgs(propertyName); this.PropertyChanged(this, args); } } }
IsSelected と IsExpanded が似てるから、すっごくリファクタしたいけどとりあえず。
Children 初回アクセス時に、子要素を列挙するようにしてる。動的な追加とか知らん。
MXML はこんな感じで。
<Window x:Class="FileFolderPractice1.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" Initialized="Window_Initialized"> <Grid> <TreeView ItemsSource="{Binding Path=Children}" Height="Auto" Width="Auto" HorizontalAlignment="Left" Name="treeView1" VerticalAlignment="Top"> <TreeView.ItemContainerStyle> <Style TargetType="{x:Type TreeViewItem}"> <Setter Property="IsExpanded" Value="{Binding Path=IsExpanded, Mode=TwoWay}" /> <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" /> <Setter Property="FontWeight" Value="Normal" /> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="FontWeight" Value="Bold" /> </Trigger> </Style.Triggers> </Style> </TreeView.ItemContainerStyle> <TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding Path=Children}"> <TextBlock Text="{Binding Path=Name}" /> </HierarchicalDataTemplate> </TreeView.ItemTemplate> </TreeView> </Grid> </Window>
で、MainWindow でルートを作る。
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Window_Initialized(object sender, EventArgs e) { ModelDataValue model = new ModelDataValue(null, @"C:\"); this.DataContext = model; } }