Expand Databound Treeview Item WPF - c#

how can I expand my bound item in treeview?
My item's class:
public class TreeViewItemBase : INotifyPropertyChanged
{
private bool isSelected;
public bool IsSelected
{
get { return this.isSelected; }
set
{
if (value != this.isSelected)
{
this.isSelected = value;
NotifyPropertyChanged("IsSelected");
}
}
}
private bool isExpanded;
public bool IsExpanded
{
get { return this.isExpanded; }
set
{
if (value != this.isExpanded)
{
this.isExpanded = value;
NotifyPropertyChanged("IsExpanded");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
public class FileModelViewTreeView : TreeViewItemBase
{
public int Level
{
get;
set;
}
public string Name
{
get;
set;
}
public string Path
{
get;
set;
}
public List<FileModelViewTreeView> SubItems
{
get;
set;
}
}
This code doesn't works by me:
((FileModelViewTreeView)toSelectIndex).IsExpanded = true;
((FileModelViewTreeView)toSelectIndex).IsSelected = true;
My treeview xaml code:
<TreeView SelectedItemChanged="FilesTreeView_SelectedItemChanged" x:Name="FilesTreeView" Margin="0,68,0,0" HorizontalAlignment="Left" Width="200" Background="Transparent" BorderBrush="#4c607a" BorderThickness="2">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:FileModelViewTreeView}" ItemsSource="{Binding SubItems}">
<StackPanel Orientation="Horizontal" Margin="2">
<Image Source="pack://application:,,,/UI/Images/dir.png"
Width="21"
Height="21"
SnapsToDevicePixels="True"/>
<TextBlock Padding="5" Text="{Binding Name}"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
All solutions which I found on other forums didn't worked for me :(
There are no exception at runtime and compiling, it just doesn't works. Maybe anyone already had that problem, please help me.

The cleanest way to do this is using a style.
<Style x:Key="MyTreeViewItemContainerStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
...
</style>
<Style TargetType="{x:Type TreeView}">
<Setter Property="ItemContainerStyle" Value="{StaticResource MyTreeViewItemContainerStyle}" />
</Style>
Check out my blog post for my take on how to handle WPF TreeViews in a MVVM context.

Related

Can columns in WPF datagrid hold different types of data

I'm trying to display different rows in a datagrid with different cellcontent sometimes.
I have different classes for the different rows, for example
Class 1:
Name - Description - Checkbox
Class 2:
Name - Description - Textbox(user input at runtime) - Checkbox
Class 3
Name - Textbox(user input at runtime)
The classes are related by inheritance so I can use them within the same observablecollection.
I want to display these in a datagrid based on which class I chose to add, for example:
ObservableCollection<Rowitem> rowitems = new ObservableCollection<Rowitem>();
rowitems.Add(new Class1("Tom", "Nice", false));
rowitems.Add(new Class2("John", "Strange", Empty textbox , true));
rowitems.Add(new Class3("Roger", Empty Textbox));
.. meaning I would like the datagrid to display an empty textbox in the third column on the second row where there is a checkbox in the first row and nothing in the third row. Is this possible?
Here is my suggestion:
<Window x:Class="DataGridDynamicCellView.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:DataGridDynamicCellView"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="525"
Height="350"
mc:Ignorable="d">
<Window.DataContext>
<local:DynamicCellsDataContext />
</Window.DataContext>
<Grid>
<DataGrid ItemsSource="{Binding DataGridSource}">
<DataGrid.Resources>
<DataTemplate DataType="{x:Type local:PresentedByCheckBox}">
<Grid HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<CheckBox HorizontalAlignment="Center"
VerticalAlignment="Center"
IsChecked="{Binding IsChecked,
UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type local:PresentedByTextBox}">
<Grid HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{Binding HelloWorld,
UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type local:PresentedByComplexBox}">
<StackPanel HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Orientation="Horizontal">
<Ellipse Height="10" Width="10" Fill="Pink"/>
<CheckBox HorizontalAlignment="Center"
VerticalAlignment="Center"
IsChecked="{Binding Checked,
UpdateSourceTrigger=PropertyChanged}" />
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{Binding HelloWorld,
UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</DataTemplate>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="BorderBrush" Value="Green" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<ContentControl Content="{Binding}" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.Resources>
</DataGrid>
</Grid></Window>
MVVM view model:
public class DynamicCellsDataContext:BaseObservableObject
{
public DynamicCellsDataContext()
{
DataGridSource = new ObservableCollection<object>
{
new PresentedByTextBox("Hello world!!!"),
new PresentedByCheckBox(true),
new PresentedByComplexBox("Hello world!!!", true),
};
}
public ObservableCollection<object> DataGridSource { get; set; }
}
public class PresentedByComplexBox:BaseObservableObject
{
private string _helloWorld;
private bool _checked;
public string HelloWorld
{
get { return _helloWorld; }
set
{
_helloWorld = value;
OnPropertyChanged();
}
}
public bool Checked
{
get { return _checked; }
set
{
_checked = value;
OnPropertyChanged();
}
}
public PresentedByComplexBox(string helloWorld, bool isChecked)
{
HelloWorld = helloWorld;
Checked = isChecked;
}
}
public class PresentedByCheckBox:BaseObservableObject
{
private bool _isChecked;
public bool IsChecked
{
get { return _isChecked; }
set
{
_isChecked = value;
OnPropertyChanged();
}
}
public PresentedByCheckBox(bool isChecked)
{
IsChecked = isChecked;
}
}
public class PresentedByTextBox:BaseObservableObject
{
private string _helloWorld;
public string HelloWorld
{
get { return _helloWorld; }
set
{
_helloWorld = value;
OnPropertyChanged();
}
}
public PresentedByTextBox(string helloWorld)
{
HelloWorld = helloWorld;
}
}
The BaseObservableObject class:
public class BaseObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChanged<T>(Expression<Func<T>> raiser)
{
var propName = ((MemberExpression)raiser.Body).Member.Name;
OnPropertyChanged(propName);
}
protected bool Set<T>(ref T field, T value, [CallerMemberName] string name = null)
{
if (!EqualityComparer<T>.Default.Equals(field, value))
{
field = value;
OnPropertyChanged(name);
return true;
}
return false;
}
}
That's all, let me know in case you will need more examples.
Best regards.
You can do this using DataTemplates:
Just add them to the Resources of your Grid:
<Grid.Resources>
<DataTemplate DataType="{x:Type local:Class1}">
<-- Template for class1 -->
</DataTemplate>
<DataTemplate DataType="{x:Type local:Class2}">
<-- Template for class2 -->
</DataTemplate>
</Grid.Resources>

Add textbox in Checkboxlist for particular item checked WPF

I am creating a application using WPF. I am able to bind Checkboxlist by using the below code:
XAML:
<DataTemplate x:Key="defaultTemplate">
<dxe:CheckEdit x:Name="lstcheckbox" Checked="lstcheckbox_Checked_1" Content="{Binding Name}" IsChecked="{Binding Path=Checked}" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=Checked}" Value="true">
<Setter TargetName="lstcheckbox" Property="ContentTemplate" Value="{DynamicResource Template1}"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<DataTemplate x:Key="Template1">
<TextBox Width="100"></TextBox>
</DataTemplate>
<local:SomeTemplateSelector x:Key="SomeTemplateSelector" DefaultTemplate="{StaticResource defaultTemplate}"
Template1="{StaticResource Template1}">
</local:SomeTemplateSelector>
</Window.Resources>
<Grid>
<dxd:DockLayoutManager x:Name="dockManager" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.VerticalScrollBarVisibility="Visible">
<dxd:LayoutGroup Caption="Review Checklist" Orientation="Vertical" ShowCaption="True" GroupBorderStyle="Group" CaptionAlignMode="AlignInGroup">
<dxd:LayoutControlItem>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Margin="8,5,5,5">Safety Equipment</TextBlock>
<!--<ListView x:Name="lstSafEquip" Grid.Column="0" Grid.Row="1" BorderThickness="0" Margin="5,5,5,5" SelectionMode="Multiple" ItemsSource="{Binding}" ItemTemplateSelector="{StaticResource SomeTemplateSelector}" ItemTemplate="{StaticResource ItemDataTemplate}" IsSynchronizedWithCurrentItem="true" ScrollViewer.VerticalScrollBarVisibility="Auto" MaxHeight="200" />-->
<ListView x:Name="lstSafEquip" Grid.Column="0" Grid.Row="1" BorderThickness="0" Margin="5,5,5,5" ItemsSource="{Binding}" ItemTemplateSelector="{StaticResource SomeTemplateSelector}" IsSynchronizedWithCurrentItem="true" ScrollViewer.VerticalScrollBarVisibility="Auto" MaxHeight="200" />
</Grid>
</dxd:LayoutControlItem>
</dxd:LayoutGroup>
</dxd:DockLayoutManager>
</Grid>
CS:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
BindCheckBoxs(lstSafEquip);
}
private void BindCheckBoxs(ListView lst)
{
try
{
ObservableCollection<Data> Source = new ObservableCollection<Data> { new Data(1, "Apple"), new Data(2, "Mango"), new Data(3, "Others"), new Data(3, "Banana"), new Data(3, "Grapes") };
lst.ItemsSource = Source;
}
catch (Exception ex)
{
throw new Exception(ex.Message.ToString());
}
}
}
public class SomeTemplateSelector : DataTemplateSelector
{
public DataTemplate Template1 { get; set; }
public DataTemplate DefaultTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
Data _Item = (Data)item;
if (_Item.Name == "Others")
{
return Template1;
}
return DefaultTemplate;
}
}
DATA.CS:
public class Data
{
public int ID { get; set; }
public string Name { get; set; }
public bool Checked { get; set; }
public Data(int _ID, string _Name)
{
ID = _ID;
Name = _Name;
Checked = false;
}
}
PROBLEM:
I want to add textbox just below the checkboxlist item Others when user will checked this item.
By using the above code trigger enter textbox for each item when i checked.
please let me know where i am going wrong. I will try my best to provide more info if needed.
From what i understood from your post and comments:
Add a TextBox as Barptad suggested but use a BooleanToVisibilityCollapsed Converter as stated below:
BooleanToVisibilityCollapsedConverter.cs:
public class BooleanToVisibilityCollapsedConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
return ((bool) value) ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture) {
//never used
return null;
}
}
XAML:
<DataTemplate x:Key="defaultTemplate">
<StackPanel>
<dxe:CheckEdit x:Name="lstcheckbox" Checked="lstcheckbox_Checked_1" Content="{Binding Name}" IsChecked="{Binding Path=Checked}" />
<TextBox Visibility="{Binding IsChecked, ElementName=lstcheckbox}"/>
</StackPanel>
</DataTemplate>
If you use Visibility.Hidden the textbox is not visible but still takes place.
After merging all suggestions and comments. I reached on the solution.
XAML:
Added textbox in default template
<DataTemplate x:Key="defaultTemplate">
<StackPanel>
<dxe:CheckEdit x:Name="lstcheckbox" Checked="lstcheckbox_Checked_1" Unchecked="lstcheckbox_Checked_1" Content="{Binding Name}" IsChecked="{Binding Path=Checked}" />
<TextBox Name="txtOther" Visibility="{Binding Path=Visible}" Text="test" Width="100"></TextBox>
</StackPanel>
</DataTemplate>
XAML.CS:
private void lstcheckbox_Checked_1(object sender, RoutedEventArgs e)
{
Data some = (sender as CheckEdit).DataContext as Data;
if (some.Name.Contains("Others"))
{
some.Visible = ToggleVisibility(some.Visible);
}
}
private Visibility ToggleVisibility(Visibility visibility)
{
return visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
}
DATA.CS:
Added visible property and inherited with INotifyPropertyChanged to track change in property in Data.cs
public class Data : INotifyPropertyChanged
{
private Visibility _visible;
public int ID { get; set; }
public string Name { get; set; }
public bool Checked { get; set; }
//public Visibility Visible { get; set; }
public Visibility Visible
{
get { return this._visible; }
set
{
this._visible = value;
RaisePropertyChanged("Visible");
}
}
public Data(int _ID, string _Name,Visibility _visible)
{
ID = _ID;
Name = _Name;
Visible = _visible;
}
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
SomeTemplateSelector.CS
public class SomeTemplateSelector : DataTemplateSelector
{
public DataTemplate OthersTemplate { get; set; }
public DataTemplate DefaultTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
return DefaultTemplate;
}
}
Hope this will help others.
Correct Me If I am worng!
U want to show textbox only under "Others" item when it is checked.
For the scenario mentioned above u need to have two different templates that changes on the value of item.
For e.g if the item is "Others" it should have template that have a text box just below check box which is only shown when checkbox is checked otherwise collapsed.
for the second type of items it should have different template even if it is checked no textbox should be displayed under it.
(Step 1) Create a Template Selector
public class ValueDataTemplateSelector : DataTemplateSelector
{
public DataTemplate DefaultTemplate { get; set; }
public DataTemplate OthersTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
{
DataTemplate template = DefaultTemplate;
CheckList data = item as CheckList;
if (data.Description.Contains("Others"))
{
template = OthersTemplate;
}
return template;
}
}
Reference assembly in your file.
(Step 3) Create two templates as given below
<Window.Resources>
<DataTemplate x:Key="DefaultTemplate">
<StackPanel>
<CheckBox IsChecked="{Binding Path=IsChecked}" Content="{Binding Path=Description}"></CheckBox>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="OthersTemplate">
<DataTemplate.Resources>
<Style TargetType="TextBox">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsChecked}" Value="false">
<Setter Property="Visibility" Value="Collapsed"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</DataTemplate.Resources>
<StackPanel>
<CheckBox IsChecked="{Binding Path=IsChecked}" Content="{Binding Path=Description}"></CheckBox>
<TextBox x:Name="othersTextBox">
</TextBox>
</StackPanel>
</DataTemplate>
<local:ValueDataTemplateSelector x:Key="CheckListTemplateSelector"
DefaultTemplate="{StaticResource DefaultTemplate}"
OthersTemplate="{StaticResource OthersTemplate}"/>
</Window.Resources>

Disable comboxboxitem by binding to data bool

I have a ComboBox in a UWP project. I am binding the DataSource to a collection of MyItem class. My class looks like this:
public class MyItem : INotifyPropertyChanged
{
#region INPC
public event PropertyChangedEventHandler PropertyChanged;
protected void Notify(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
private string _ItemName;
public string ItemName
{
get { return _ItemName; }
set
{
if (value != _ItemName)
{
_ItemName = value;
Notify("ItemName");
}
}
}
private bool _ItemEnabled;
public bool ItemEnabled
{
get { return _ItemEnabled; }
set
{
if (value != _ItemEnabled)
{
_ItemEnabled = value;
Notify("ItemEnabled");
}
}
}}
Now I want the ComboBoxItem to be enabled or disabled depending on my ItemEnabled property. I researched and tried adding a binding through the Style tag but the binding does not function in UWP.
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="IsEnabled" Value="{Binding ItemEnabled}" />
</Style>
</ComboBox.ItemContainerStyle>
How can I solve this?
EDIT 1: Binding code
<ComboBox ItemsSource="{Binding Path=MyItemsCollection, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=ItemName}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Just remove this line (ItemsSource="{Binding Path=MyItemsCollection, UpdateSourceTrigger=PropertyChanged}") in XAML and add this line after InitializeComponent(); in the code behind:
<ComboBox Name="cmb1">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=ItemName}" />
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="IsEnabled" Value="{Binding ItemEnabled}" />
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
And in xaml.cs:
public Window1()
{
InitializeComponent();
cmb1.ItemsSource = MyItemsCollection;
}
Edit: Another way is like this:
public Window1()
{
InitializeComponent();
this.DataContext = MyItemsCollection;
}
And in the xaml:
<ComboBox Name="cmb1" ItemsSource="{Binding}">
....

How to bind TreeView to ViewModel?

I have a view model as follows:
public class SolutionViewModel : TreeViewItemViewModel {
public ObservableCollection<TreeViewItemViewModel> Children {
get { return mChildItems; }
}
public bool IsExpanded {
get { return mIsExpanded; }
set {
if (value != mIsExpanded) {
mIsExpanded = value;
OnPropertyChanged("IsExpanded");
}
if (mIsExpanded && mParentItem != null)
mParentItem.IsExpanded = true;
if (this.HasDummyChild) {
Children.Remove(EmptyItem);
LoadChildren();
}
}
}
public bool IsSelected {
get { return mIsSelected; }
set {
if (value != mIsSelected) {
mIsSelected = value;
OnPropertyChanged("IsSelected");
}
}
}
protected override void LoadChildren() {
var subFolders = default(ReadOnlyCollection<Folder>);
if (!GetSubFolders(mSolution.Folder.Name, out subFolders)) {
subFolders = new ReadOnlyCollection<Folder>(new List<Folder>());
}
foreach (var folder in subFolders) {
Children.Add(new SolutionItemViewModel(this, folder));
}
}
public string SolutionName {
get { return mSolution.Name; }
}
}
The .Xaml for the TreeView is as follows:
<TreeView Name="SolutionTree" ItemsSource="{Binding SolutionViewModel}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type localmodels:SolutionViewModel}"
ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<Image Width="16" Height="16" Margin="3,0" Source="..\Resources\Folder_25x25.png" />
<TextBlock Text="{Binding SolutionName}" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
After a file is selected from SolutionExplorer:
public void SetBindingContext(SolutionViewModel SolutionViewModel) {
SolutionTree.DataContext = SolutionViewModel;
}
This is a lazy loading model so that when the item is expanded, the children are loaded.
The problem is that I am not even getting the Solution Name as the top level node.
Update:
I verified that the model has SolutionName assigned:
In addition, per comment from #elgonzo, I edited the .Xaml to reflect a change to ItemsSource binding:
<TreeView Name="SolutionTree" ItemsSource="{Binding}">
<TreeView.ItemContainerStyle>
Update 2
Code to assign the TreeView data context is executed when an event handler is raised after selecting a file from the OpenFileDialog:
private void OnOpenFile(string FilePath) {
mSolutionManager = SolutionManager.Load(FilePath);
mSolutionViewModel = new SolutionViewModel(mSolutionManager.Solution);
mMainWindow.SolutionExplorer.SetBindingContext(mSolutionViewModel);
mSolutionViewModel.Refresh();
}
When I step into the Refresh() method:
public void Refresh() {
OnPropertyChanged("SolutionName");
}
...I find that the PropertyChangedEventHandler has no subscribers.
Your binding to ItemsSource is wrong :
<TreeView Name="SolutionTree" ItemsSource="{Binding SolutionViewModel}">
ItemSource needs to be an IEnumerable.

How to bind the property to the selected node in the Treeview in WPF

How to bind the custom property to the selected node's IsSelected property in MVVM,
I have loaded the nodes at runtime into the treeview. I am using MVVM
Here's a small example:
public abstract class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class MyViewModel : ViewModel
{
public ObservableCollection<Item> Items
{
get
{
return new ObservableCollection<Item>()
{
new Item() {DisplayValue = "Item1", IsSelected = false, Sample = "Sample: I am Item1"},
new Item() {DisplayValue = "Item2", IsSelected = true, Sample = "Sample: I am Item2"},
new Item() {DisplayValue = "Item3", IsSelected = false, Sample = "Sample: I am Item3"}
};
}
}
}
public class Item : ViewModel
{
public string DisplayValue { get; set; }
private bool _isSelected = false;
public bool IsSelected
{
get
{
return _isSelected;
}
set
{
_isSelected = value;
OnPropertyChanged("IsSelected");
}
}
private string _sample;
public string Sample
{
get
{
return _sample;
}
set
{
_sample = value;
OnPropertyChanged("Sample");
}
}
}
XAML:
<Window x:Class="WpfApplication93.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication93"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.DataContext>
<local:MyViewModel></local:MyViewModel>
</Grid.DataContext>
<StackPanel>
<TreeView x:Name="myTreeView" ItemsSource="{Binding Items}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected}"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeViewItem">
<TextBlock Text="{Binding DisplayValue}"></TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<!-- if you want to customize the appearance of a selected element do it here -->
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
<Label Content="{Binding ElementName=myTreeView, Path=SelectedItem.Sample}"></Label>
</StackPanel>
</Grid>
</Window>

Categories