I am building a webscaper to scrape torrents, backend is already done and now I am kind of stuck on the UI(using WPF).
I want to display the torrents on a ListBox but corresponding to the query (I call it term as in search term).
The data passed to the ListBox is:
List<SearchTermData>
This is the structure:
public class SearchTermData {
public string SearchTerm { get; set; }
public List<Torrent> Torrents { get; set; } = new List<Torrent>();
}
Torrent is this:
public class Torrent {
public string Name { get; set; }
public string Size { get; set; }
}
I generally want the ListBox to display a Grid. Column 1 will be the "SearchTerm" and column 2 will be a StackPanel of "Torrents" (List<Torrent>).
It displays the "SearchTermData" correctly, with the SearchTerm name and the general structure, but it fails to display the StackPanel of the Torrents.
This is my XAML style:
<Style x:Key="TorrentListbox" TargetType="ListBox">
<Setter Property="UseLayoutRounding" Value="True" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="BorderBrush" Value="{StaticResource Black}"/>
<Setter Property="Background" Value="Transparent" />
<Setter Property="FontFamily" Value="{StaticResource DefaultFont}" />
<Setter Property="FontWeight" Value="Regular" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="SelectionMode" Value="Multiple" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.CanContentScroll" Value="True" />
<Setter Property="ItemContainerStyle" Value="{DynamicResource TermItem}" />
</Style>
<Style x:Key="TermItem" TargetType="ListBoxItem">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="BorderBrush" Value="{StaticResource DSGray}"/>
<Setter Property="Foreground" Value="{StaticResource Black}" />
<Setter Property="FontFamily" Value="{StaticResource DefaultFont}" />
<Setter Property="FontWeight" Value="Regular" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Margin" Value="0,0,0,4"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True" />
<Setter Property="UseLayoutRounding" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="0" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true">
<Grid Background="{TemplateBinding Background}" HorizontalAlignment="Stretch" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Visibility="Visible">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Content="{Binding Path=SearchTerm}" BorderThickness="0,0,2,0" BorderBrush="{StaticResource Black}" Style="{StaticResource KeyLabel}" Foreground="{StaticResource DSGreen}" FontWeight="Bold" VerticalContentAlignment="Top" Grid.Row="0" Grid.Column="0"/>
<StackPanel Grid.Row="0" Grid.Column="1">
<ItemsControl ItemsSource="{Binding Path=Torrents}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="{StaticResource DSGreen}">
<ItemsControl ItemsSource="{Binding Torrent}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Visibility="Visible">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Content="{Binding Path=Name}" Style="{StaticResource PropertyLabel}" Grid.Row="0" Grid.Column="0"/>
<Label Content="Size:" Style="{StaticResource KeyLabel}" Grid.Row="0" Grid.Column="1"/>
<Label Content="{Binding Path=Size}" Style="{StaticResource PropertyLabel}" Grid.Row="0" Grid.Column="2"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
If anyone can help me figure out the issue I would appreciate it a lot!
In your items template for Torrent, there is a nested ItemsControl that is not needed and that is binding to a property Torrent on an item of type Torrent, which does not exist.
<ItemsControl ItemsSource="{Binding Torrent}">
The control template below should work. I removed the redundant ItemsControl and the StackPanel as well, because it only contains a single control, which is why you do not need it.
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="0" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true">
<Grid Background="{TemplateBinding Background}" HorizontalAlignment="Stretch" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Visibility="Visible">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Content="{Binding Path=SearchTerm}" BorderThickness="0,0,2,0" BorderBrush="{StaticResource Black}" Style="{StaticResource KeyLabel}" Foreground="{StaticResource DSGreen}" FontWeight="Bold" VerticalContentAlignment="Top" Grid.Row="0" Grid.Column="0"/>
<ItemsControl Grid.Row="0" Grid.Column="1" ItemsSource="{Binding Path=Torrents}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="{StaticResource DSGreen}">
<Grid HorizontalAlignment="Stretch" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Visibility="Visible">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Content="{Binding Path=Name}" Style="{StaticResource PropertyLabel}" Grid.Row="0" Grid.Column="0"/>
<Label Content="Size:" Style="{StaticResource KeyLabel}" Grid.Row="0" Grid.Column="1"/>
<Label Content="{Binding Path=Size}" Style="{StaticResource PropertyLabel}" Grid.Row="0" Grid.Column="2"/>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Border>
</ControlTemplate>
An Alternative Using ListView with GridView
Since you want to display two columns, you could alternatively use a ListView in combination with a GridView. This way, you would actually have real columns.
<ListView ItemsSource="{Binding SearchTerms}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="BorderBrush" Value="{StaticResource DSGray}"/>
<Setter Property="Foreground" Value="{StaticResource Black}" />
<Setter Property="FontFamily" Value="{StaticResource DefaultFont}" />
<Setter Property="FontWeight" Value="Regular" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Margin" Value="0,0,0,4"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True" />
<Setter Property="UseLayoutRounding" Value="True" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="0" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true">
<GridViewRowPresenter/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Search Term">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding Path=SearchTerm}" BorderThickness="0,0,2,0" BorderBrush="Black" Foreground="Green" FontWeight="Bold"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Torrents">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding Torrents}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="Green">
<Grid HorizontalAlignment="Stretch" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Visibility="Visible">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Content="{Binding Path=Name}" Grid.Row="0" Grid.Column="0"/>
<Label Content="Size:" Grid.Row="0" Grid.Column="1"/>
<Label Content="{Binding Path=Size}" Grid.Row="0" Grid.Column="2"/>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
I created a custom WPF ComboBox like this:
<ComboBox
x:Name="ComboBoxBtn"
VerticalAlignment="Top"
HorizontalAlignment="Left"
Margin="0,0,0,-1"
Width="300"
ItemsSource="{Binding Source, RelativeSource={RelativeSource AncestorType=UserControl}}"
SelectedItem="{Binding Path=Selected, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=UserControl}}"
IsSynchronizedWithCurrentItem="True">
<ComboBox.ItemTemplate>
<DataTemplate>
<ContentControl>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding Favorite}" Value="True">
<Setter Property="Content">
<Setter.Value>
<Grid>
<Grid.Style>
<Style TargetType="Grid">
<Setter Property="Background" Value="#FFE6E6FA"/>
</Style>
</Grid.Style>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Content="{Binding}" Width="250" />
<Button Grid.Column="1" Command="{Binding AddCommandButton, ElementName=root}"
CommandParameter="{Binding}">+</Button>
</Grid>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Favorite}" Value="False">
<Setter Property="Content">
<Setter.Value>
<Grid>
<Grid.Style>
<Style TargetType="Grid">
<Setter Property="Background" Value="Yellow"/>
</Style>
</Grid.Style>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Content="{Binding}" Width="250" />
<Button Grid.Column="1" Command="{Binding RemoveCommandButton, ElementName=root}"
CommandParameter="{Binding}">-</Button>
</Grid>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
The Source binding contains a ObservableColleciton where the client has a Favorite field and is supposed to show a different background and a different button. But when I open the ComboBox all the items have:
"System.Windows.Styles"
Your problem is you are setting Style as Content in the Content Control.
<ContentControl>
<Style TargetType="ContentControl">
...
</Style>
</ContentControl>
In order to set the style of the content control you should add:
<ContentControl.Style>
So the code above will look like this:
<ContentControl>
<ContentControl.Style>
<Style TargetType="ContentControl">
...
</Style>
<ContentControl.Style>
</ContentControl>
EDIT
By the way your code is very complex for the simple task of changing the background. Here is a simplified version:
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid Name="PART_GRID" Background="Yellow">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Content="{Binding}"
Width="250" />
<Button Name="PART_BUTTON"
Grid.Column="1"
Content="-"
Command="{Binding AddCommandButton, ElementName=root}"
CommandParameter="{Binding}" />
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Favorite}"
Value="True">
<Setter TargetName="PART_GRID"
Property="Background"
Value="#FFE6E6FA" />
<Setter TargetName="PART_BUTTON"
Property="Content"
Value="+" />
<Setter TargetName="PART_BUTTON"
Property="Command"
Value="{Binding RemoveCommandButton, ElementName=root}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ComboBox.ItemTemplate>
In my case, I found that I had:
<ComboBox>
<Style>
</Style>
</ComboBox>
which was directly adding a style as an item, which is similar to the solution above.
I'm trying to develop an universal app for personal use, however I am running into the problem that the second column in my ListView doesn't align properly, I have the following XAML:
<ListView
Grid.Row="1"
ItemsSource="{Binding Items, UpdateSourceTrigger=PropertyChanged}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Stretch="None" Source="{Binding Image}" />
<TextBlock Grid.Column="0" Grid.Row="2" Text="{Binding Name}" HorizontalAlignment="Center" />
<Image Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" Source="{StaticResource HighAlchImage}" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Which results in the following image:
However, I want the second image (the one that's the same every time) to align with itself, preferably with the width of the first Column to be Auto. Is this possible?
You need to stretch width of the ListViewItem to the width of the ListView.
i.e. You have to set HorizontalContentAlignment of the ListView's ItemContainerStyle to Stretch.
Normally I would create a copy of the Default ListViewItemStyle, then do my customization based on the default style:
(put the following code inside <ListView> Tag)
<ListView.Resources>
<!-- Better to put this to another XAML file -->
<Style x:Key="ListViewItemStyleDefault" TargetType="ListViewItem">
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="TabNavigation" Value="Local"/>
<Setter Property="IsHoldingEnabled" Value="True"/>
<Setter Property="Padding" Value="12,0,12,0"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="MinWidth" Value="{ThemeResource ListViewItemMinWidth}"/>
<Setter Property="MinHeight" Value="{ThemeResource ListViewItemMinHeight}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<ListViewItemPresenter CheckBrush="{ThemeResource SystemControlForegroundBaseMediumHighBrush}" ContentMargin="{TemplateBinding Padding}" CheckMode="Inline" ContentTransitions="{TemplateBinding ContentTransitions}" CheckBoxBrush="{ThemeResource SystemControlForegroundBaseMediumHighBrush}" DragForeground="{ThemeResource ListViewItemDragForegroundThemeBrush}" DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}" DragBackground="{ThemeResource ListViewItemDragBackgroundThemeBrush}" DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}" FocusBorderBrush="{ThemeResource SystemControlForegroundAltHighBrush}" FocusSecondaryBorderBrush="{ThemeResource SystemControlForegroundBaseHighBrush}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" PointerOverForeground="{ThemeResource SystemControlHighlightAltBaseHighBrush}" PressedBackground="{ThemeResource SystemControlHighlightListMediumBrush}" PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}" PointerOverBackground="{ThemeResource SystemControlHighlightListLowBrush}" ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}" SelectedPressedBackground="{ThemeResource SystemControlHighlightListAccentHighBrush}" SelectionCheckMarkVisualEnabled="True" SelectedForeground="{ThemeResource SystemControlHighlightAltBaseHighBrush}" SelectedPointerOverBackground="{ThemeResource SystemControlHighlightListAccentMediumBrush}" SelectedBackground="{ThemeResource SystemControlHighlightListAccentLowBrush}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ListViewItemStyleStretch" TargetType="ListViewItem" BasedOn="{StaticResource ListViewItemStyleDefault}">
<!-- Magic here -->
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.Resources>
<ListView.ItemContainerStyle>
<StaticResource ResourceKey="ListViewItemStyleStretch"/>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<!-- Your ItemTemplate... -->
</ListView.ItemTemplate>
The Grid panel has such functionality built in. In order to utilize it you should set SharedSizeGroup on your column definitions, and then set attached Grid.IsSharedSizeScope on the element parenting all grids which should share column sizes (ListView would be a good choice in your case).
<ListView Grid.Row="1"
ItemsSource="{Binding Items, UpdateSourceTrigger=PropertyChanged}"
Grid.IsSharedSizeScope="True">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column1" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Column2" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Stretch="None" Source="{Binding Image}" />
<TextBlock Grid.Column="0" Grid.Row="2" Text="{Binding Name}" HorizontalAlignment="Center" />
<Image Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" Source="{StaticResource HighAlchImage}" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
You might want to take some care while choosing values for SharedSizeGroup properties - preferably, they should be unique per visual tree.
Do it the opposite:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
This way your first column will use the space it needs and the second column will be aligned.
Searching for a solution, I ended up here, #Ryan answer is near to solve my problem, but some adjusts must be done.
1 Create An style:
<Style x:Key="LstViewItemContainerStyle" TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
2 Apply style to the list view as this:
<ListView
...
ItemContainerStyle="{StaticResource LstViewItemContainerStyle}">
</ListView>
I have a design for my user control. The control contains many rows and columns and inside it has sub-grids and rows and columns. One of the inner most row contains a ListView whose Horizontal and Vertical Scroll bar set to Auto.
I am able to view Horizontal Scroll bar for listview as well as the outer most grid, but I am unable to view Vertical Scroll bar for listview, but for the outer grid is working fine.
Here is the xaml for the same.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" VerticalAlignment="Center" Margin="8,0,0,0">
<Image Source="pack://application:,,,/EMC.DD.CommonFrameworkLayer;component/Images/Items1.png" Width="50" Height="50"></Image>
<TextBlock Text="Items" VerticalAlignment="Center" Style="{StaticResource DashboardTextBlockStyle}" Margin="8,0,0,0" ></TextBlock>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="1" Background="#eaeaea" Margin="8,0,0,0">
<Image Source="pack://application:,,,/EMC.DD.CommonFrameworkLayer;component/Images/HomeDashBoard.png"></Image>
<TextBlock Text="DashBoard" Style="{StaticResource HomeDashBoardTextBlockStyle}" VerticalAlignment="Center" Margin="8,0,0,0"></TextBlock>
<TextBlock Text=">" VerticalAlignment="Center" Margin="5,0,0,0" Style="{StaticResource HomeDashBoardTextBlockStyle}" FontWeight="Medium"></TextBlock>
<TextBlock Text="Items" VerticalAlignment="Center" Margin="5,0,0,0" Style="{StaticResource HomeDashBoardTextBlockStyle}" FontWeight="Medium"></TextBlock>
<TextBlock x:Name="ItemsTextBlock" x:FieldModifier="private" Margin="5,0,0,0" VerticalAlignment="Center"></TextBlock>
</StackPanel>
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Grid.Row="2" Grid.Column="0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" VerticalAlignment="Center" Margin="8,10,0,10">
<TextBox x:Name="ItemTextBox" MinWidth="160" Height="25">
</TextBox>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Center" Margin="8,2,0,10">
<ComboBox x:Name="CategoryComboBox" DisplayMemberPath="CategoryName" SelectedValue="CategoryID" SelectedValuePath="CategoryName"
Margin="2,2,0,3" MinHeight="27" MinWidth="250" Grid.Row="2" Grid.Column="2" HorizontalAlignment="Left" Grid.ColumnSpan="2" SelectedIndex="-1"/>
<Button Style="{StaticResource CRUDButtonStyle}" Content="Search" Margin="5,0,0,0" Click="SearchButton_Click"></Button>
<StackPanel Orientation="Horizontal" Margin="150,0,0,0">
<Button Style="{StaticResource CRUDButtonStyle}" Content="New Item" Click="ItemButton_Click" ></Button>
<Button Style="{StaticResource CRUDButtonStyle}" Content="Delete Item" Margin="5,0,0,0" Click="DeleteButton_Click"></Button>
<Button Style="{StaticResource CRUDButtonStyle}" Content="Delete All" Margin="2,0,0,0" Click="DeleteAllItem_Click"></Button>
</StackPanel>
</StackPanel>
<Grid Grid.Row="2" Margin="8,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="900"/>
<ColumnDefinition Width="Auto" MinWidth="200"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*"/>
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Border Grid.Row="0" Style="{StaticResource DefaultBorderStyle}">
<StackPanel Grid.Row="0" Orientation="Horizontal" VerticalAlignment="Top" Margin="0,0,0,0">
<Image Source="pack://application:,,,/EMC.DD.CommonFrameworkLayer;component/Images/Items1.png"></Image>
<TextBlock Text="List Of Items" Margin="5,0,0,0" VerticalAlignment="Center"
Style="{StaticResource HomeDashBoardTextBlockStyle}" FontWeight="Normal"/>
</StackPanel>
</Border>
<ListView x:Name="ItemsListView" x:FieldModifier="private" Grid.Row="1" MouseDown="ListViewItem_PreviewMouseDown"
SelectionChanged="ListView_SelectionChanged" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListView.Resources>
<Style TargetType="{x:Type GridViewColumnHeader}" x:Key="MyHeaderStyle">
<Setter Property="FontFamily" Value="Segoe UI Light"/>
<Setter Property="FontWeight" Value="DemiBold"></Setter>
<Setter Property="Height" Value="30"></Setter>
</Style>
<local:IntToBoolConverter x:Key="IntBoolKey"></local:IntToBoolConverter>
<Style x:Key="TextStyle" TargetType="{x:Type TextBlock}">
<EventSetter Event="Hyperlink.Click" Handler="EditClicked" />
</Style>
<local:BackgroundConverter x:Key="BackgroundKey"/>
<Style x:Key="columnHeaderContianerStyle" TargetType="ListViewItem">
<Setter Property="Background">
<Setter.Value>
<Binding RelativeSource="{RelativeSource Self}" Converter="{StaticResource BackgroundKey}"/>
</Setter.Value>
</Setter>
<!--<EventSetter Event="PreviewMouseDown" Handler="ListViewItem_PreviewMouseDown"></EventSetter>-->
</Style>
<Style x:Key="myHeaderStyle" TargetType="{x:Type GridViewColumnHeader}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="#1570a6"/>
<Setter Property="Foreground" Value="#FFFFFF"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="#000000"/>
</Trigger>
</Style.Triggers>
</Style>
</ListView.Resources>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource columnHeaderContianerStyle}">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView AllowsColumnReorder="true" ColumnHeaderContainerStyle="{StaticResource MyHeaderStyle}">
<GridViewColumn Width="50" HeaderContainerStyle="{StaticResource myHeaderStyle}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Width ="20" Height="20" IsChecked="{Binding Path=IsActive,Converter={StaticResource IntBoolKey}}"></CheckBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Item ID" Width="110" DisplayMemberBinding="{Binding Path=ItemID,Mode=OneWay}"
HeaderContainerStyle="{StaticResource myHeaderStyle}"/>
<GridViewColumn Header="Item Name" Width="200" DisplayMemberBinding="{Binding Path=ItemName,Mode=OneWay}"
HeaderContainerStyle="{StaticResource myHeaderStyle}"/>
<GridViewColumn Header="Item Price" Width="200" DisplayMemberBinding="{Binding Path=Price,Mode=OneWay}"
HeaderContainerStyle="{StaticResource myHeaderStyle}" >
</GridViewColumn>
<GridViewColumn Header="Category" Width="200" DisplayMemberBinding="{Binding Path=Category.CategoryName,Mode=OneWay}"
HeaderContainerStyle="{StaticResource myHeaderStyle}"/>
<GridViewColumn Header="Item Image" Width="200" HeaderContainerStyle="{StaticResource myHeaderStyle}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Image Width="100" Height="50" VerticalAlignment="Center" HorizontalAlignment="Center"
Source="{Binding Path=ItemImagePath,Mode=OneWay}"></Image>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="100" HeaderContainerStyle="{StaticResource myHeaderStyle}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Name="urlToContent" MinWidth="150" Width="Auto" Style="{StaticResource TextStyle}">
<Hyperlink NavigateUri="{Binding Path=URL}" Name="hlkURL">
<TextBlock Text="Edit" HorizontalAlignment="Center"/>
</Hyperlink>
</TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
<Grid Grid.Column="1">
<GroupBox x:Name="ItemDetails" Header="Item Details" FontFamily="Segoe UI" HorizontalAlignment="Center" Margin="2,-10,0,0"
VerticalAlignment="Top" Height="Auto" Width="Auto" Grid.Row="0">
<Grid Margin="2,5,0,0" HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10" />
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Item Name" FontFamily="Segoe UI" VerticalAlignment="Center" HorizontalAlignment="Right" Grid.Row="0" Grid.Column="1"
Margin="0,0,0,5"/>
<TextBlock x:Name="ItemNameTextBlock" Text="{Binding Path=ItemName,Mode=OneWay}" FontFamily="Segoe UI" FontWeight="DemiBold" VerticalAlignment="Top"
HorizontalAlignment="Left" Grid.Row="0" Grid.Column="2" Margin="5,0,0,0"/>
<TextBlock Text="Category" FontFamily="Segoe UI" VerticalAlignment="Center" HorizontalAlignment="Right" Grid.Row="1" Grid.Column="1"
Margin="0,0,0,5"></TextBlock>
<TextBlock x:Name="CategoryTextBlock" Text="{Binding Path=Category.CategoryName,Mode=OneWay}" FontFamily="Segoe UI" FontWeight="DemiBold" VerticalAlignment="Top"
HorizontalAlignment="Left" Grid.Row="1" Grid.Column="2" Margin="5,0,0,0"/>
<TextBlock Text="Item Quantity" FontFamily="Segoe UI" VerticalAlignment="Center" HorizontalAlignment="Right" Grid.Row="2" Grid.Column="1"
Margin="0,0,0,5"></TextBlock>
<TextBlock x:Name="ItemQuantityTextBlock" Text="{Binding Path=ItemQuantity,Mode=OneWay}" FontFamily="Segoe UI" FontWeight="DemiBold" VerticalAlignment="Top"
HorizontalAlignment="Left" Grid.Row="2" Grid.Column="2" Margin="5,0,0,0"/>
</Grid>
<ListView x:Name="ItemIngredientsListView" Grid.Row="1" Margin="2,0,0,5" ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListView.Resources>
<Style TargetType="{x:Type GridViewColumnHeader}" x:Key="MyHeaderStyle">
<Setter Property="FontFamily" Value="Segoe UI Light"/>
<Setter Property="FontWeight" Value="DemiBold"></Setter>
<Setter Property="Height" Value="30"></Setter>
</Style>
<Style x:Key="myHeaderStyle" TargetType="{x:Type GridViewColumnHeader}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="#1570a6"/>
<Setter Property="Foreground" Value="#FFFFFF"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="#000000"/>
</Trigger>
</Style.Triggers>
</Style>
<local:BackgroundConverter x:Key="BackgroundKey"/>
<Style x:Key="columnHeaderContianerStyle" TargetType="ListViewItem">
<Setter Property="Background">
<Setter.Value>
<Binding RelativeSource="{RelativeSource Self}" Converter="{StaticResource BackgroundKey}"/>
</Setter.Value>
</Setter>
<!--<EventSetter Event="PreviewMouseDown" Handler="ListViewItem_PreviewMouseDown"></EventSetter>-->
</Style>
</ListView.Resources>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource columnHeaderContianerStyle}">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView AllowsColumnReorder="true" ColumnHeaderContainerStyle="{StaticResource MyHeaderStyle}">
<GridViewColumn Header="Ingredient ID" Width="80" DisplayMemberBinding="{Binding Path=ItemIngredientID,Mode=OneWay}"
HeaderContainerStyle="{StaticResource myHeaderStyle}"/>
<GridViewColumn Header="Ingredient" Width="200" DisplayMemberBinding="{Binding Path=IngredientName,Mode=OneWay}"
HeaderContainerStyle="{StaticResource myHeaderStyle}"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</GroupBox>
</Grid>
</Grid>
</Grid>
</ScrollViewer>
</Grid>
May be I am posting huge xaml, because I am not sure where exactly went wrong in the whole user control.
Some one, please look into my xaml and tell me where exactly do I need to change the rowHeight or some thing else.
Any help highly appreciated.
The ScrollViewer of WPF provides unlimited space to its child element - I think that is what hinders you to see the vertical scroll bar of your ListView. Let's analyze your situation:
The scroll viewer provides unlimited space to its child grid (let's call it A).
A is divided into three rows: the first two rows' height will be calculated according to the content they display (<RowDefinition Height="Auto" />). The last row will take the remaining infinite space provided by the scroll viewer.
In this last row, another grid is placed (let's call it B) that has two columns and three rows. The second row takes the remaining space (still infinite) because its height is set to *.
In this very row, your list view is placed. This means that it has unlimited vertical space within the WPF layout system and has no need to show its vertical scroll bar.
A solution might be to limit the height of this row but provide a GridSplitter so that the user is able to change the height. Another solution as pointed out by #pushpraj (while I was writing this) is to limit the height of the list view.
If you have any further questions, please feel free to ask.
I'm trying to change the containing border background color based on the focus property of a contained textbox. Can someone explain what's the problem with my code?
<Border BorderBrush="LightBlue" BorderThickness="2" Background="#33000000">
<Border.Style>
<Style>
<Style.Triggers>
<DataTrigger
Binding="{Binding IsFocused, ElementName=txtValue}"
Value="True">
<Setter Property="Border.Background" Value="Green" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid Margin="0" VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBox Name="txtValue" Grid.Column="0" Text="20" />
<TextBlock Grid.Column="1" />
</Grid>
</Border>
Your DataTrigger is not change the value of the Background property because you set it inside the Border declaration. So, once setted, it will never changed. To allow changing, you have to set the value inside the Style.
<Border BorderBrush="LightBlue" BorderThickness="2" >
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="#33000000"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsFocused, ElementName=txtValue}" Value="True">
<Setter Property="Background" Value="Green" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid Margin="0" VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBox Name="txtValue" Grid.Column="0" Text="20" />
<TextBlock Grid.Column="1" />
</Grid>
</Border>