How to programatcally add a button to a single TreeViewItem
I generate the contents of a TreeView(TV) dynamically and, according to certain properties of the items i'm using to source the tree, would like to attach buttons to some of the TreeViewItems(TVIs).
It just so happens that all the TVIs of one specific TV in my application needs this functionality. Something that might simplify the task is the fact that all root items in that tree need buttons. To paraphrase, every TVI inside the specific TV needs a button except those TVIs tha开发者_StackOverflowt are inside TVIs.
I was thinking template thoughts but I can only see how to add buttons to all the TVIs in the TV. Another option (i think... I haven't tried this yet but it sounds ok in my head) would be to just add buttons to everything in the TV and bind the relevant property of the source items to the visability of the buttons but this seems like a complete hack and i'm mostly convinced that there has to be a more elegant solution.
Any ideas about how to pull this off?
If you're building the data dynamically off properties in a view model, then you could look into using a DataTemplateSelector.
In the implementation, check if the data item has children. If it does, return the data template with a button. If it doesn't, return the data template without a button. Something like:
public class ButtonDataTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item,
DependencyObject container)
{
FrameworkElement element = container as FrameworkElement;
if (element != null)
{
YourClass itemAsYourClass = item as YourClass;
if(itemAsYourClass != null)
{
bool hasChildren = itemAsYourClass.Children != null
&& itemAsYourClass.Children.Count > 0;
return element.FindResource(hasChildren
? "withButtonTemplate"
: "withoutButtonTemplate"
);
}
}
return null;
}
}
Here's the code I used:
class CurrentDriveDataTemplateSelector : DataTemplateSelector { public DataTemplate currentDriveTemplate {get; set;} public DataTemplate dirTemplate { get; set; }
public override DataTemplate SelectTemplate(object item,
DependencyObject container)
{
FrameworkElement element = container as FrameworkElement;
if (element != null)
{
Directory dir = item as Directory;
if (dir != null)
{
bool isCurrentDrive = ((dir.parent == 0) && (dir.state == "current"));
if (isCurrentDrive)
{
return currentDriveTemplate;
}
return dirTemplate;
}
}
}
}
<HierarchicalDataTemplate x:Key="normalDirTemplate" ItemsSource="{Binding Path=childdirs}">
<TextBlock Text="{Binding Path=name}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="currentDriveTemplate" ItemsSource="{Binding Path=childdirs}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=name}" Width="100"/>
<Button Content="=>" Width="20"></Button>
</StackPanel>
</HierarchicalDataTemplate>
<mine:CurrentDriveDataTemplateSelector
currentDriveTemplate="{StaticResource currentDriveTemplate}"
dirTemplate="{StaticResource normalDirTemplate}"
x:Key="CurrentDriveDataTemplateSelector"/>
...blah
<TreeView Height="324" Margin="0,25,0,0" x:FieldModifier="private" x:Name="currentDirectoryTree" Width="150" ItemTemplateSelector="{StaticResource CurrentDriveDataTemplateSelector}">
...etc
精彩评论