I have a collection of items where the last column is a collection with a celltemplate of it's own.
The ListView's item source is set dynamically in code and all of the other columns are rendering correctly. However, the final column's data is not being read at all. I've tried different solutions from other questions, but they don't seem to work for me.
<Window x:Class="bbowl.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
Title="Blood Bowl Data" Height="350" Width="525">
<Window.Resources>
<DataTemplate x:Key="SkillTemplate">
<TextBlock Text="{Binding Path=name}" ToolTip="{Binding Path=description}" Height="18" HorizontalAlignment="Left" VerticalAlignment="Top" Foreground="Blue"><TextBlock.TextDecorations><TextDecoration /></TextBlock.TextDecorations></TextBlock>
</DataTemplate>
<DataTemplate x:Key="SkillsTemplate">
<DataGrid AutoGenerateColumns="False" Height="Auto" HorizontalAlignment="Left" VerticalAlignment="Top" HeadersVisibility="None" HorizontalScrollBarVisibility="Hidden" ItemsSource="{Binding Path=Skills}" BorderThickness="0" ItemTemplate="{StaticResource SkillTemplate}" />
</DataTemplate>
</Window.Resources>
<Grid>
<ComboBox HorizontalAlignment="Left" Name="cbxRace" VerticalAlignment="Top" Width="503" Height="25" SelectionChanged="cbxRace_SelectionChanged" ItemsSource="{Binding}" />
<Label Content="Rerolls:" Height="25" HorizontalAlignment="Left" Margin="0,25,0,0" Name="lblRerollLabel" VerticalAlignment="Top" Width="435" HorizontalContentAlignment="Right" FontWeight="Bold" />
<Label Content="0" Height="25" HorizontalAlignment="Left" Margin="441,25,0,0" Name="lblReroll" VerticalAlignment="Top" Width="62" HorizontalContentAlignment="Right" />
<ListView Height="263" HorizontalAlignment="Left" Margin="0,48,0,0" Name="lvwPlayer" VerticalAlignment="Top" Width="503" ItemsSource="{Binding}">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=name}"/>
<GridViewColumn Header="MA" DisplayMemberBinding="{Binding Path=ma}" />
<GridViewColumn Header="ST" DisplayMemberBinding="{Binding Path=st}" />
<GridViewColumn Header="AG" DisplayMemberBinding="{Binding Path=ag}" />
<GridViewColumn Header="Max" DisplayMemberBinding="{Binding Path=max}" />
<GridViewColumn Header="Price" DisplayMemberBinding="{Binding Path=price}" />
<GridViewColumn Header="Skills" CellTemplate="{StaticResource SkillsTemplate}"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
To solve your problem you would need to change your SkillsTemplate to something like this:
<DataTemplate x:Key="SkillsTemplate">
<DataGrid
AutoGenerateColumns="False"
HorizontalAlignment="Left"
VerticalAlignment="Top"
HeadersVisibility="None"
ItemsSource="{Binding Path=Skills}"
BorderThickness="0"
GridLinesVisibility="None">
<DataGrid.Columns>
<DataGridTemplateColumn CellTemplate="{StaticResource SkillTemplate}"/>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
which instead of changing whole items template creates one column that displays your text using SkillTemplate. However, as far I can see, for what you want to do with it you may consider using less complicated control like ListBox or even ItemsControl when you just want to display bunch of items without giving user option to select one
<DataTemplate x:Key="SkillsTemplate">
<ItemsControl ItemsSource="{Binding Path=Skills}" ItemTemplate="{StaticResource SkillTemplate}"/>
</DataTemplate>
Related
How do I insert a horizontal line after each list view item in a grid?
<Grid>
<ListView Margin="10" Name="Users">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="300">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock TextWrapping="Wrap" TextTrimming="WordEllipsis" Height="32" Text="{Binding Name}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Age" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock TextWrapping="Wrap" TextTrimming="WordEllipsis" Height="32" Text="{Binding Age}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
I tried defining Border after DataTemplate
<DataTemplate>
<Border Margin="5" BorderThickness="1" BorderBrush="SteelBlue">
but that only added a border around each of the data template items. How do I insert a horizontal separator after each row?
I think you ought to be able to set a row style via the ItemContainerStyle:
https://stackoverflow.com/a/4474474/424129
You'd want to set a BorderThickness="0,0,0,1" to have only a bottom border.
I would like to enable or disable a field when a specific value in the combobox is selected:
In my xaml, I have a ListBox (ListToTransfert)wich is filled by dragging items from another Listbox (ListViewContents).
The ListToTransfert got 3 fields: Name, Gapand Time.
The field Namecannot be edited while the 2 others can be.
When the combobox has its value changed to Gapor to Time, I want the appropriate column to be enabled while the other one is disabled.
Here is the code of my XAML:
<!-- ListViewContents -->
<Label Content="Contents" Background="White" HorizontalContentAlignment="Center" HorizontalAlignment="Left" Margin="11,16,0,0" VerticalAlignment="Top" Width="400" Height="31"/>
<ListView Background="#bdc3c7" x:Name="ListViewContents" SelectionMode="Single" Margin="11,51.826,0,11" HorizontalAlignment="Left" Width="400">
<ListView.View>
<GridView >
<GridViewColumn Header="Name" Width="350" DisplayMemberBinding="{Binding Name}"/>
</GridView>
</ListView.View>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<command:EventToCommand Command="{Binding TransferContent}"
CommandParameter="{Binding SelectedItem, ElementName=ListViewContents}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Label Content="Label" Height="100" Width="100"/>
</ListView>
<!-- ListToTransfert -->
<TextBox Style="{StaticResource {x:Static ToolBar.TextBoxStyleKey}}"
HorizontalContentAlignment="Center"
HorizontalAlignment="Left" Margin="851,16,0,0"
VerticalAlignment="Top" Width="400" Height="31" Text="{Binding groupName}" />
<ListView Background="#bdc3c7" x:Name="ListToTransfert" ItemsSource="{Binding ContentsToTransfer}" HorizontalAlignment="Right" Width="400" Margin="0,51.826,21,11">
<ListView.View>
<GridView>
<GridViewColumn Header="Amount" >
<GridViewColumn.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A" />
</Grid.ColumnDefinitions>
<TextBlock Foreground="Black" Background="AliceBlue" Text="{Binding}"/>
</Grid>
</DataTemplate>
</GridViewColumn.HeaderTemplate>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A" />
</Grid.ColumnDefinitions>
<TextBlock Foreground="Black" Background="AliceBlue" HorizontalAlignment="Right" Text="{Binding Path=Name}"/>
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Gap"></GridViewColumn>
<GridViewColumn Header="Time"></GridViewColumn>
</GridView>
</ListView.View>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<command:EventToCommand Command="{Binding DeleteContent}"
CommandParameter="{Binding SelectedItem, ElementName=ListToTransfert}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ListView>
My combobox is not yet created since i'm not sure if there is a solution for this problem, tho there is always one.
Can you propose me a XAML solution to do that?
This can be done either via a group of RadioButtons or a single ComboBox.
RadioButton
If you don't need to control this behavior from the view model, you can use the following :
<RadioButton x:Name="TimeRadioButton" Content="Time" />
<GridViewColumn Header="Gap">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<TextBlock IsEnabled="{Binding IsChecked, ElementName=GapRadioButton}"/>
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
Alternatively, you can add EnableGapColumn/EnableTimeColumn on your view model. However, it would be better if you create an enum to define this behavior :
public enum TransfertViewType
{
Gap, Time
}
And change your bindings with EnumToBooleanConverter:
<!-- put this in a resource -->
<converter:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
<RadioButton Content="Time" IsChecked="{Binding ViewType, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static vm:YourViewModel.TransfertViewType}}"/>
<TextBlock IsEnabled="{Binding ViewType, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static vm:YourViewModel.TransfertViewType}}"/>
ComboBox
It would pretty much the same as the second part of RadioButton section, except that you will need to create an IEnumerable<TransfertViewType> as the ItemsSource for the ComboBox. Or, an IDictionary<TransfertViewType, string> if you like to customize the description a little bit.
<!-- for ienumerable -->
<ComboBox ItemsSource="{Binding TransfertViewTypes}"
SelectedValue="{Binding ViewType}" />
<!-- for idictionary -->
<ComboBox ItemsSource="{Binding TransfertViewTypes}"
DisplayMemberPath="Value" SelectedValuePath="Key"
SelectedValue="{Binding ViewType}" />
How to create Check box for Column inside Listview. i was able to make checkbox for listview items. but i want to have checkbox for Column itself.like in windows:
here is code in XAML
<ListView HorizontalAlignment="Left" Grid.Row="1" Width="400">
<ListView.View>
<GridView>
<GridViewColumn Width="140" Header="Column1 With Checkbox">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Tag="{Binding}" IsThreeState="False" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="140" Header="Column2" />
<GridViewColumn Width="115" Header="Column3" />
</GridView>
</ListView.View>
</ListView>
Note that this will only make checkboxes for items not Column itself. so how to make this happen?
You can make the header a custom control by defining it under the GridViewColumn.Header property.
<ListView HorizontalAlignment="Left" Grid.Row="1" Width="400">
<ListView.View>
<GridView>
<GridViewColumn Width="140">
<GridViewColumn.Header>
<StackPanel Orientation="Horizontal">
<Checkbox IsChecked="{Binding YourCheckedProperty}" />
<TextBlock Text="Column1" />
</StackPanel>
<GridViewColumn.Header>
</GridViewColumn>
<GridViewColumn Width="140" Header="Column2" />
<GridViewColumn Width="115" Header="Column3" />
</GridView>
</ListView.View>
</ListView>
There probably was a topic in which lays the solution for my problem but I've spend too much hours on this so I've decided to ask.
I have a ListView to which I've binded a collection of processes. And I have a ListBox in which I want to place Threads of a selected process. Binding in ListView works, but analogical in ListBox doesn't.
Here's my .xaml:
<Window x:Class="TaskManager.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window" Height="453" Width="533" Icon="/TaskManager;component/Images/taskmgr.png">
<Grid>
<ListView Height="276" HorizontalAlignment="Left" Name="processesView" VerticalAlignment="Top" Width="503" ItemsSource="{Binding ProcessList}">
<ListView.View>
<GridView AllowsColumnReorder="False">
<GridViewColumn DisplayMemberBinding="{Binding ProcessName}">
<GridViewColumn.Header>
<GridViewColumnHeader Click="nameColumnHeader_Click">
Name
</GridViewColumnHeader>
</GridViewColumn.Header>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding Id}">
<GridViewColumn.Header>
<GridViewColumnHeader Click="IDColumnHeader_Click">
ID
</GridViewColumnHeader>
</GridViewColumn.Header>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding BasePriority}">
<GridViewColumn.Header>
<GridViewColumnHeader Click="priorityColumnHeader_Click">
Priority
</GridViewColumnHeader>
</GridViewColumn.Header>
</GridViewColumn>
<GridViewColumn Header="Keep alive">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox x:Name="keepAliveBox" IsChecked="{Binding EnableRaisingEvents}" Checked="keepAliveBox_Checked" Unchecked="keepAliveBox_Unchecked" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<ListBox Height="120" HorizontalAlignment="Left" Margin="93,282,0,0" Name="threadBox" VerticalAlignment="Top" Width="200" ItemsSource="{Binding ElementName=processesView, Path=SelectedItem.Threads}">
<ListBox.ItemTemplate>
<DataTemplate>
<!--<ListBoxItem Content="{Binding}"/>-->
<Label Content="{Binding Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
After execution I can't see anything in the ListBox but if I click inside something is selected. So if I change the above to Content="TEST" I can see several Labels with "TEST" value. So it seems that I'm binding the name somehow incorrectly.
Here's the .cs part where I set the context:
public MainWindow()
{
InitializeComponent();
processesView.DataContext = this;
threadBox.DataContext = this;
...
}
Items were invisible but selectable so it was probable that I was binding the wrong thing. And that's the reason. I was binding to Name property of Thread whilst Process has a collection of ProcessThreads which don't have that property. Here's the fix in .xaml:
<ListBox Height="120" HorizontalAlignment="Left" Margin="93,282,0,0" Name="threadBox" VerticalAlignment="Top" Width="200" ItemsSource="{Binding ElementName=processesView, Path=SelectedItem.Threads}">
<ListBox.ItemTemplate>
<DataTemplate>
<Label Content="{Binding Path=Id}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Can't wait for XAML debugger in Visual Studio 2015.
I have created a small app, for which View part is as below.
I have used ListView for showing my data. This table (ListView) is being updated once I enter the data and click on Save. After which if I click on the data, the whole row is selected.
But I am not sure how to click an individual cell.
Can I do it using ListView? If Yes how? Or I need some other component?
VehicalForm.xaml
<Window x:Class="Seris.VehicalForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="500" Width="600">
<WrapPanel Orientation="Vertical" Margin="10 " >
<Label Content="Vehical No" HorizontalAlignment="Left"/>
<TextBox Name="VehicalNo_Text" Height="23" Width="80" TextWrapping="Wrap" Text="{Binding VehicalNo}" HorizontalAlignment="Left" />
<Label Content="Model" HorizontalAlignment="Left"/>
<TextBox Name="Model_Text" Height="23" Width="80" TextWrapping="Wrap" Text="{Binding Model}" HorizontalAlignment="Left" />
<Label Content="Manufacturing Date" HorizontalAlignment="Left"/>
<DatePicker Name="ManufacturingDate_DateTime" SelectedDate="{Binding ManufacturingDate, Mode=TwoWay}"/>
<Label Content="IU No" HorizontalAlignment="Left"/>
<TextBox Height="23" Width="80" Name="IUNO_Text" TextWrapping="Wrap" Text="{Binding IUNo}" HorizontalAlignment="Left"/>
<Label Content="Personnel" HorizontalAlignment="Left"/>
<ComboBox Name="Personnel_Combo" Text="{Binding Personnel}" HorizontalAlignment="Left" Width="116"/>
<Separator Height="20" RenderTransformOrigin="0.5,0.5" Width="16"/>
<Button Name="Save_Button" Command="{Binding SaveButton_Command}" Content="Save" Width="66"/>
<Label x:Name="Error_Label" Content="{Binding ErrorMessage, UpdateSourceTrigger=PropertyChanged}" Foreground="Red" HorizontalAlignment="Left" Height="41" Width="137"/>
<ListView Height="294" Width="371" ItemsSource="{Binding ListItems, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" >
<ListView.View>
<GridView>
<GridViewColumn Header="Vehical No" DisplayMemberBinding="{Binding VehicalNo}" />
<GridViewColumn Header="Model" DisplayMemberBinding="{Binding Model}" />
<GridViewColumn Header="ManufacturingDate" DisplayMemberBinding="{Binding ManufacturingDate}" />
<GridViewColumn Header="IUNo" DisplayMemberBinding="{Binding IUNo}" />
<GridViewColumn Header="Personnel" DisplayMemberBinding="{Binding Personnel}" />
</GridView>
</ListView.View>
</ListView>
</WrapPanel>
</Window>
You can achieve this with a DataGrid. Replace your listview with something like this;
<DataGrid Height="294" Width="371" ItemsSource="{Binding ListItems, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" SelectionUnit="Cell" SelectionMode="Single" AutoGenerateColumns="False">
<DataGridTextColumn Header="Vehical No" Binding="{Binding VehicalNo}" />
<DataGridTextColumn Header="Model" Binding="{Binding Model}" />
<DataGridTextColumn Header="ManufacturingDate" Binding="{Binding ManufacturingDate}" />
<DataGridTextColumn Header="IUNo" Binding="{Binding IUNo}" />
<DataGridTextColumn Header="Personnel" Binding="{Binding Personnel}" />
</DataGrid>
Two important properties of the DataGrid are;
SelectionUnit="Cell" SelectionMode="Single"
These allow you to control how a user can select items. In this example you can only select a single cell.