How to Create DropdownList with CheckBox in WPF application? - wpf

I am new to WPF. I wan to create a Dropdown List which will contain CheckBox items in to it as show in image. Is it Possible?

This is not the perfect solution to your question, but maybe it helps you anyway.
(You don't have to use <Canvas> but i like it because it's more comfortable to place elements)
<Canvas>
<ListBox Canvas.Left="280" Canvas.Top="40" Width="170">
<ListBoxItem>
<TreeView>
<TreeViewItem Header="Outboard">
<TreeViewItem Header="Generic">
<CheckBox>Bronze</CheckBox>
<CheckBox>Clear</CheckBox>
</TreeViewItem>
<TreeViewItem Header="Guardian">
<CheckBox>Clear</CheckBox>
<CheckBox>UltraWhite</CheckBox>
</TreeViewItem>
</TreeViewItem>
</TreeView>
</ListBoxItem>
</ListBox>
</Canvas>
Sry can't post a picture yet because i don't have enough Reputations.
So i uploaded it.
http://imageshack.us/scaled/thumb/849/examplezt.png
I used a Listbox instead of a Combobox and you only can check the latest items.

Related

Powershell and WPF Treeview

I'm currently working on a powershell tool where I need to create a gui. It seems that according to my needs I would need to use WPF instead of Windows Form. The treeview control in windows forms doesn't let you customize the treeview items. Here is a sample of what I need :
Basically I would need to add treeviewitems on the fly. According to the nodeLevel, I would need to apply different image and progress bar. I would also need to be able to change the visibility of these controls. And all of these will be accomplished using powershell.
Can someone show me a direction, how should I approach this ? How/where should I start ?
You can use standard XAML for WPF to create window with arbitrary controls, events, styles and so on. Then call XamlReader.Load() to create a WPF Window object and Window.ShowDialog() to show it.
# WPF Window with XAML
[xml]$xaml = #"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="Window" Title="WPF Window from PowerShell" WindowStartupLocation = "CenterScreen"
Width = "800" Height = "600" ShowInTaskbar = "True">
<TreeView>
<TreeViewItem Header="Group 1">
<TreeViewItem Header="Item 1">
<StackPanel Orientation="Horizontal">
<Image Source="image.png" />
<TextBlock Text="Level 2.0" />
<ProgressBar Minimum="0" Maximum="100" Name="Progress" Width="100" IsIndeterminate="True"/>
<Button>Start</Button>
</StackPanel>
</TreeViewItem>
<TreeViewItem Header="Item 1"></TreeViewItem>
<TreeViewItem Header="Item 1"></TreeViewItem>
</TreeViewItem>
<TreeViewItem Header="Group 2">
<TreeViewItem Header="Item 1"></TreeViewItem>
<TreeViewItem Header="Item 1"></TreeViewItem>
<TreeViewItem Header="Item 1"></TreeViewItem>
</TreeViewItem>
</TreeView>
</Window>
"#
$XmlNodeReader=(New-Object System.Xml.XmlNodeReader $xaml)
$Window=[Windows.Markup.XamlReader]::Load($XmlNodeReader)
$Window.ShowDialog()

Hierarchical TreeList View WPF

Basically I need to implement a control like this one in WPF, preferably with MVVM support:
(source: msdn.com)
How can I achieve that?
You need something like this using TreeView with some styles for TreeViewItem :
<TreeView>
<TreeViewItem Header="Employee1">
<TreeViewItem Header="Jesper"/>
<TreeViewItem Header="Aaberg"/>
<TreeViewItem Header="12345"/>
</TreeViewItem>
</TreeView>
or you can take a look at Tekerik controls : http://www.telerik.com/products/wpf/overview.aspx
which as controls as you wish but sure with a price :)

Adding a small popup on a wpf listbox that is already using itemsource

Here is a portion of my wpf-xaml code :
<ListBox x:Name="TestJobSuiteListBox" Grid.Row="1" ItemsSource="{Binding AvailableJobs}" MouseRightButtonDown="TestJobSuiteListBox_OnMouseRightButtonDown">
<ListBox.ItemTemplate>
<HierarchicalDataTemplate>
<ListBoxItem Content="{Binding Name}"/>
</HierarchicalDataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I would like to add another listboxitem to that ListBox and I dont want it to be visible before you rightclick on the listbox. It also should not be bound to the "AvailableJobs" property.
Something like this :
<ListBox x:Name="TestJobSuiteListBox" Grid.Row="1" ItemsSource="{Binding AvailableJobs}" MouseRightButtonDown="TestJobSuiteListBox_OnMouseRightButtonDown">
<ListBox.ItemTemplate>
<HierarchicalDataTemplate>
<ListBoxItem Content="{Binding Name}"/>
</HierarchicalDataTemplate>
</ListBox.ItemTemplate>
<ListBoxItem x:Name="AddJobbListBoxItem" Visibility="Hidden"></ListBoxItem>
</ListBox>
This doesn't work, because of "itemsource must be empty problem"
Anyone have a good Idea of how I could do it ?
I don't need help with the visibility/rightclick functionality.
Thanks in advance, I hope the problem is understandable.
You can put listbox to stackPanel, and disable it's scrolling. Then add that one element also to the stackPanel under the listbox, and finally add that stackPanel to scrollViewer. Then you have listbox with AddButton.
<ScrollViewer>
<StackPanel>
<ListBox ItemsSource="{Binding AvailableJobs}"
ScrollViewer.VerticalScrollBarVisibility="Disabled">
<!-- ... -->
</ListBox>
<Button x:Name="AddJobbButton" Visibility="Collapsed" />
</StackPanel>
</ScrollViewer>
Notice that if you have lots of items in listbox, there might be some performance problems, because I'm not sure that listbox's virtualizing is working correctly if it's in stackPanel.
EDIT: of course you have to listen mouse events and set then button's visibility to visible and so on...
I think you have to use ItemTemplateSelector to achieve this functionality. You can create different DataTemplate as per your requirement in the Resources section and bind properly in the xaml. Check the answer here, it will give you the idea about the approach. Please refer this examlpe also. Hope this will help.

DataBinding to selected TreeViewItem only if child of other TreeViewItem

I have a custom class (NewBlockLabelInfo) with an observable collection of another custom class (DoorControllerLabelInfo) I've successfully databound the NewBlockLabelInfo class to the treeview, and everything displays fine.
I have a lot of textboxs that are data bound to certain properties, and updating these reflects in the treeview.
I'd like to databind one set of textboxs for the properties, to the selected item in the treeview IF the selected item is a child of the specified treeviewitem (Observable Collection, Door Controllers)
The Data Context is specified at the window level.
I've looked long and hard for a way to do this, let alone the best way.
Heres the WPF XAML for the TreeView
<TreeView Margin="12,150,582,16" Name="treeView1">
<TreeViewItem Header="{Binding Path=BlockName}" Style="{StaticResource BlockItem}" IsExpanded="True">
<TreeViewItem Style="{StaticResource PhoneNoItem}" Header="{Binding Path=TelephoneNumber}"/>
<TreeViewItem Style="{StaticResource DataNoItem}" Header="{Binding Path=DataNumber}"/>
<TreeViewItem Style="{StaticResource CompanyItem}" Header="{Binding Path=CompanyName}"/>
<TreeViewItem Style="{StaticResource ConnectedItem}" Header="{Binding Path=ConnectedDC}" />
<TreeViewItem IsExpanded="True" Header="Door Controllers" Foreground="#FF585858" ItemsSource="{Binding Path=DoorControllers, UpdateSourceTrigger=PropertyChanged}" Name="DCTreeViewItem" Selected="DCTreeViewItem_Selected">
<TreeViewItem.ItemTemplate>
<HierarchicalDataTemplate>
<TreeViewItem Header="{Binding Path=DCName}" Style="{StaticResource DCItem}" IsExpanded="True" Selected="DCTreeViewItem_Selected" >
<TreeViewItem Header="{Binding Path=Address}" Style="{StaticResource AddressItem}" />
<TreeViewItem Header="{Binding Path=Channel1}" Style="{StaticResource Door1Item}" />
<TreeViewItem Header="{Binding Path=Channel2}" Style="{StaticResource Door2Item}" />
</TreeViewItem>
</HierarchicalDataTemplate>
</TreeViewItem.ItemTemplate>
</TreeViewItem>
<TreeViewItem IsExpanded="True" Header="Flats" Foreground="#FF585858" ItemsSource="{Binding Path=FlatNames, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
<TreeViewItem.ItemTemplate>
<DataTemplate>
<TreeViewItem Header="{Binding}" Style="{StaticResource FlatsItem}" IsExpanded="True">
</TreeViewItem>
</DataTemplate>
</TreeViewItem.ItemTemplate>
</TreeViewItem>
</TreeViewItem>
</TreeView>
How can I bind a textbox to a selected item property (or to the databound class property) of a TreeViewItem only if it is a child of Door Controllers TreeViewItem
Thank you in advance
Oliver
You would likely be best served with defining a DataTemplate selector, and creating several datatemplates. The selector can evaluate all kinds of logical rules, and return the template that you want.
Here is a pretty good getting started tutorial on DataTemplateSelectors.
EDIT
After rereading your question here is what I have got.
Do your model classes have navigation properties to get to parent objects? If so, you can use triggers (or more preferable if you are using MVVM) properties on the ViewModel to enable/disable/alter visibility based on what the parent object is rather than the parent TreeViewItem. It is a bit more difficult to access the visual tree the way you are describing.
I solved this myself by adding an event handler on click for each of the child TreeViewItems I am concerned with. With this I could then get the DataContext from it, and set it to be the DataContext of the TextBoxs, and create my own bindings.
Since DataContext retrieval is done by reference, and not by value this works.
Here is the event handler for when one of the child nodes are clicked than I am concerned with: (Forgive the temporary naming)
private void DCTreeViewItem_Selected(object sender, RoutedEventArgs e)
{
TreeViewItem currentItem = (TreeViewItem)e.OriginalSource;
textBox5.DataContext = ((DoorControllerLabelInfo)currentItem.DataContext);
Binding b = new Binding("DCName");
b.Mode = BindingMode.TwoWay;
b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(textBox5, TextBox.TextProperty, b);
}
From this, I set the path, binding mode, and update source trigger in the XAML so that only the Data Context need to be updated.
Thanks
Oliver

Keyboard Navigation fails when there are hidden items in TreeView

So I have a TreeView like the one below, with certain items being hidden. If I try to go through the tree using arrow keys, I get stuck at the items surrounding the "collapsed" items. Try it yourself.
<Window x:Class="Example.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TreeViewBug" Height="300" Width="300">
<Grid>
<TreeView>
<TreeViewItem Header="a." />
<TreeViewItem Header="b" Visibility="Collapsed" />
<TreeViewItem Header="c." />
<TreeViewItem Header="d" />
<TreeViewItem Header="e." />
<TreeViewItem Header="f" Visibility="Collapsed"/>
<TreeViewItem Header="g." />
<TreeViewItem Header="h" />
</TreeView>
</Grid>
</Window>
Nobody else seems to have posted this question (or blogged about it) and so I'm posting it in the hopes of getting a non-hacky solution to this. So here's my question:
How do I fix this bug?
I'm planning on extending the default TreeView to skip items with Visibility set to Hidden/Collapsed or IsEnabled set to false. Has anybody else encountered this before and come up with a good solution?
I don't understand why this happens.
I could fix it by adding:
IsEnabled="False"
to the collapsed items. Then, navigation works as you'd expect.
Here's a solution that works: Disable the item you are hiding. If the item is disabled, keyboard navigation works as it is supposed to. So whenever you set the Visibility of the item, set IsEnabled to false when the item is not visible.
Try the code in the question but add IsEnabled="false" to all the collapsed items. It should work.

Resources