CheckBox state of a CellTemplate in ListView - wpf

i am trying to use styles to prevent from repeting code, by putting them in a Resource Disctionary.
My question is, when we have a GridViewColumn in a ListView, which one of the columns have a DataTemplate, and in that DataTemplate we have the CellTemplate with only a CheckBox, can we bind the CheckBox state when the DataTemplete is in a ResourceDictionary?
What i have is this in my XAML:
<ListView Name="listView">
<ListView.View>
<GridView AllowsColumnReorder="False">
<GridViewColumn DisplayMemberPath="{Binding [1]}"/>
<GridViewColumn DisplayMemberPath="{Binding [2]}"/>
<GridViewColumn DisplayMemberPath="{Binding [4]}"/>
<GridViewColumn DisplayMemberPath="{Binding [5]}"/>
<GridViewColumn DisplayMemberPath="{Binding [6]}"/>
<GridViewColumn DisplayMemberPath="{Binding [7]}"/>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsThreeState="False" IsChecked="{Binding [8]}" Unchecked="CheckBox_Changed" Checked="CheckBox_Changed"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
And i am trying to do something like this in the Resource Dictionary:
<DataTemplate x:Key="ListViewCheckboxCell">
<StackPanel>
<CheckBox IsThreeState="False" IsChecked="Make reference"/>
</StackPanel>
</DataTemplate>
And the values in that column is always a bool.
Thanks in advance!

What you did seems correct. You'll now have to write
<GridViewColumn CellTemplate="{StaticResource ListViewCheckboxCell}" />
The template will be taken into account, you can leave exactly the same template than the original in your resource dictionary: The binding is dynamically resolved, so when the XAML will be read, bindings will automatically be set to the related object, following what you indicated

Related

Putting ComboBox in a one special row in ListView in WPF

How to put a Combobox to a special row of a listview (WPF, VB.net)?
There is a ListView that has two columns. The columns are "Parameter" and "Values". The second column has different types (such as numbers, strings and "Selectable values") and is editable. The "Selectable values" have to appear in a Combobox.
One of the ways that I think about, is conditional XAML tags (I don`t know if it is possible or not ?) .
I tried this code but it shows Combobox for all rows in listview :
<ListView x:Name="listView"
HorizontalAlignment="Left"
Height="237"
Margin="40,34,0,0"
VerticalAlignment="Top"
Width="447"
ItemsSource="{Binding Values}">
<ListView.View>
<GridView>
<GridViewColumn Header="Parameter"
DisplayMemberBinding="{Binding Path=LName}"
Width="100" />
<GridViewColumn Header="Value"
Width="150">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=ListView}, Path=ItemsSource}"
Width="120">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Type}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
I only want to use Combobox for one row while the type of the rest of rows are double or string. How can I do this?

How to add several Checkboxs columns

I have ListView binding with my collection:
private List<MyData> Col;
ItemsSource="{Binding Col}"
I define this inside my ListView:
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="Selected">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox x:Name="cbSelect" IsChecked="{Binding SupportedVendors}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding Name}" Header="Name" Width="100"/>
<GridViewColumn DisplayMemberBinding="{Binding ID}" Header="ID" Width="600"/>
</GridView.Columns>
</GridView>
</ListView.View>
Now i want channge my object bool value inside my Collcection once the user change the CheckBox.
I can i do that ? (i need it in code behaind)
Tag the object of your collection with the CheckBox, the on check /uncheck you can get the tag from the checkbox checked. Change the bool value in the object.

Treeview with Grid inside in WPF

I want to display a simple schema of a database in a treeview with 1 level of depth.
So I have a collection of tables, whose name I'd like to display as a header of the elements, and for each table a collection of columns with name, type, etc..
However in each table I want to display those columns definition in a grid, with a header specifying the properties of the columns definition, and in each row, the definition itself.
One way to make this work is to see that as a treeview where each table has a sequence of one child (the entire collection of column definition), then displayed as a grid :
<TreeView ItemsSource="{Binding Tables}" x:Name="treeView" MinWidth="400" >
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Path=ListofONEelement}">
<TextBlock Text="{Binding Path=TableName}" />
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<ListView ItemsSource="{Binding GroupOfColumnDefinition}">
<ListView.View>
<GridView>
<GridViewColumn Header="ColumnName" DisplayMemberBinding="{Binding Path=Item1}" />
<GridViewColumn Header="Model" DisplayMemberBinding="{Binding Path=Item2.Model}" />
<GridViewColumn Header="ColumnStatus" DisplayMemberBinding="{Binding Path=Item2.ColumnStatus}" />
<GridViewColumn Header="ColumnType" DisplayMemberBinding="{Binding Path=Item2.ColumnType}" />
</GridView>
</ListView.View>
</ListView>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
But I had to create this intermediate structure ListofONEelement to make this works, as hierarchy in the treeview exists only if there are items to enumerate.
Are there other, nicer ways to do this, directly in XAML, that would not require to have a custom type created in my ViewModel ?
Actually put the one item in the TreeView. Don't use HierarchicalDataTemplate.
<TreeView ItemsSource="{Binding Tables}">
<TreeView.ItemTemplate>
<DataTemplate>
<TreeViewItem Header="{Binding TableName}">
<ListView ItemsSource="{Binding GroupOfColumnDefinition}">
<ListView.View>
<GridView>
<GridViewColumn Header="ColumnName" DisplayMemberBinding="{Binding Path=Item1}" />
<GridViewColumn Header="Model" DisplayMemberBinding="{Binding Path=Item2.Model}" />
<GridViewColumn Header="ColumnStatus" DisplayMemberBinding="{Binding Path=Item2.ColumnStatus}" />
<GridViewColumn Header="ColumnType" DisplayMemberBinding="{Binding Path=Item2.ColumnType}" />
</GridView>
</ListView.View>
</ListView>
</TreeViewItem>
</DataTemplate>
</TreeView.ItemTemplate>
</TreeView>

WPF nested objects databinding

Hi I am having issues with understanding WPF databinding with nested objects.
I have a workgroup class containing a List of User_activation objects called ListMembers and I would like to display its properties. How do I access its nested properties? This class contains another object called User that has its username and ultimately I would like to display the username in the combobox instead of WPF_test.User_activation.
Below is the XAML code and corresponding layout:
<ListView x:Name="ListViewWorkgroups" VerticalAlignment="Top" Height="Auto" Width="Auto" ItemsSource="{Binding listWorkgroups}">
<ListView.View>
<GridView>
<GridViewColumn Width="auto" Header="Workgroup" DisplayMemberBinding="{Binding Name}"></GridViewColumn>
<GridViewColumn Width="auto" Header="Skills">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding ListSkills}" ></ComboBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="auto" Header="Members">
<GridViewColumn.CellTemplate>
<DataTemplate >
<ComboBox IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding ListMembers}" ></ComboBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Layout: http://i50.tinypic.com/ydy5h.png
Thank you!
You need to set the ItemTemplate for the ComboBox
<ComboBox IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding ListMembers}" >
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding User.Username}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
As an alternative, if you don't need anything complex you can bind the DisplayMemberPath
<ComboBox IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding ListMembers}" DisplayMemberPath="{Binding User.Username}"/>
You use the "." to access properties like you would in normal c# code
This is just a follow-up to the previous answer. I just discovered that in Bindings, you may use a leading period in a filesystem fashion:
<ComboBox ItemsSource="{Binding .ListMembers}">
<DataTemplate>
<TextBlock Text="{Binding .User.Username}"/>
</DataTemplate>
That syntax adds nothing semantically, but in some cases makes the statement more readable (and XAML can certaintly use that!)
Here's a better example:
<ComboBox ItemsSource="{Binding Caliber}" DisplayMemberPath=".Thickness" />
where Thickness is a property of Caliber.

WPF Databinding ListView to a Property of an object which can be nothing

I'm trying to create a Window with a ListView and an Area where details to the selected Object are displayed. The Listview displays items stored in an ObservableCollection(Of T) Collection. The items itself contain also an ObservableCollecton(Of T) Collection which should then be displayed in the details area in another ListView, accordingly to the selected item of the first ListView.
The Problem:
The InitializeComponent() throws an Exception (XAMLParseException).
Exception:
Set property 'System.Windows.Controls.GridViewColumn.DisplayMemberBinding' threw an exception.
InnerException:
Object of type 'System.String' cannot be converted to type 'System.Windows.Data.BindingBase'.
The Line- and ColumNumer of the Exception are Pointing at the <GridView> of my ListView (.View)
This is the First ListView
<ListView ItemsSource="{Binding Path=MyObjectCollection, Mode=OneWay}" SelectedItem="{Binding Path=Selected, Mode=OneWayToSource}">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Path=Name, Mode=OneWay}">
<GridViewColumnHeader Content="Name" />
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
And this is the second ListView
<ListView ItemsSource="{Binding Path=SelectedItem.MySubCollection, Mode=OneWay}">
<ListView.View>
<GridView> <!-- Thats the Line where the Exception is pointing at -->
<GridViewColumn Width="150" DisplayMemberBinding="Key">
<GridViewColumnHeader Content="Key" />
</GridViewColumn>
<GridViewColumn Width="150" DisplayMemberBinding="Value">
<GridViewColumnHeader Content="Value" />
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
So. How can I bind to the Collection Property of an Object could be nothing?
From the exception message the problem is with with your DisplayMemberBinding in the second listview. Because you have to provide a Binding expression instead of a string see MSDN. Like in your first listview:
<ListView ItemsSource="{Binding Path=SelectedItem.MySubCollection, Mode=OneWay}">
<ListView.View>
<GridView> <!-- Thats the Line where the Exception is pointing at -->
<GridViewColumn Width="150" DisplayMemberBinding="{Binding Path=Key}">
<GridViewColumnHeader Content="Key" />
</GridViewColumn>
<GridViewColumn Width="150" DisplayMemberBinding="{Binding Path=Value}">
<GridViewColumnHeader Content="Value" />
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>

Resources