WPF KeyDown does not fire in StackPanel - c#

There are StackPanels in Listbox. MouseDown does work, but KeyDown - doesn't. KeyDown works in Listbox.
[EDIT: suggestion about "visible" didn't work for me. I post more code, maybe the problem is connected with other circumstances in the code]
<Window x:Class="PWSG_LAB_4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ABCD"
mc:Ignorable="d"
Title="Password Manager" Height="500" Width="700" Icon="abc.png"
Loaded="Window_Loaded">
<Window.Resources>
<local:NumberConverter x:Key="konwert"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="400"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="180"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Menu IsMainMenu="True" >
<MenuItem Header="Main menu">
<MenuItem Header="Save file" Click="MenuItem_Click" />
<MenuItem Header="Exit" Click="MenuItem_Click" />
</MenuItem>
</Menu>
<TreeView Name="Drzewo" Grid.Row="1" SelectedItemChanged="SelectionChanged">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:TreeElement}" ItemsSource="{Binding Items}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}" />
<TextBlock Text=" [" Foreground="Blue" />
<TextBlock Foreground="Blue">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource konwert}" Mode="OneWay">
<Binding ElementName="TreeElementItems.Count"/>
<Binding ElementName="hasla.Count"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<TextBlock Text="]" Foreground="Blue" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
<ListBox Grid.Row="1" Grid.Column="1" Name="listahasel" ItemsSource="{Binding}" AlternationCount="2" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Name="panelzhaslami" Orientation="Vertical" Height="90" Width="400" Background="Blue" Focusable="True" MouseRightButtonDown="mouseDownPanel" KeyDown="keydownonpanel">
<TextBlock FontSize="20" Text="{Binding placeofwork}" Padding="4"/>
<TextBlock FontSize="14" Text="{Binding login}" Padding="4"/>
<TextBlock FontSize="14" Text="{Binding password}" Padding="4"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ProgressBar Visibility="Hidden" Grid.Row="2" Grid.Column="1" Minimum="0" Height="20" Width="200" Maximum="10" Value="0" Name="Pasek" HorizontalAlignment="Right"/>
</Grid>

If your StackPanel needs to receive keyboard inputs, it must first receive the keyboard focus.
Then, from MSDN, in order for a StackPanel to receive keyboard focus, it must be focusable (Focusable = true) and visible (IsVisible = true). By default, panels are not focusable, so you need to manually set it to focusable.
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Focusable="True"
MouseDown="mouseDownPanel" KeyDown="keydownonpanel">
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Related

Binding in WPF not propagating into usercontrol

I am new and learning WPF. I am making a demo project to learn the working of binding and dependency properties. To make it easy to understand I briefly explain this project. In solution, I have three projects. Two projects are user control and one is the main application.
This is user control for the child page
<UserControl x:Class="DefectTracking.DefectTrace"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="1200"
Grid.IsSharedSizeScope="True"
Loaded="ElementGeladen"
Name="Self">
<UserControl.Resources>
<ResourceDictionary Source="Resources.xaml" />
</UserControl.Resources>
<UserControl.Style>
<Style TargetType="{x:Type UserControl}">
<Setter Property="Background" Value="{StaticResource Hintergrundfarbe}"/>
</Style>
</UserControl.Style>
<Grid DataContext="{Binding ElementName=Self}" Margin="4">
<FrameworkElement x:Name="ProxyElement"/>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<!--#region Kopfzeile -->
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Ergebnisse"/>
<ColumnDefinition SharedSizeGroup="Name"/>
<ColumnDefinition SharedSizeGroup="Folgefehler" Width="*"/>
<ColumnDefinition SharedSizeGroup="Fehler"/>
<ColumnDefinition SharedSizeGroup="Aktiviert"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="2" Style="{StaticResource FolgefehlerStil}" Text="FF" />
<TextBox Grid.Column="3" Style="{StaticResource FehlerStil}" Text="Fehler"/>
<TextBox Grid.Column="4" Style="{StaticResource FehlerStil}" Text="Aktiviert"/>
</Grid>
<!--#endregion-->
<!--#region Prüfung -->
<ItemsControl Grid.Row="1" ItemsSource="{Binding Prüfungen}" Name="Prüfungselement">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Background="Black">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Ergebnisse"/>
<ColumnDefinition SharedSizeGroup="Name"/>
<ColumnDefinition SharedSizeGroup="Folgefehler"/>
<ColumnDefinition SharedSizeGroup="Fehler"/>
<ColumnDefinition SharedSizeGroup="Aktiviert"/>
</Grid.ColumnDefinitions>
<!--#region Ergebnisse -->
<ItemsControl Grid.Column="0" ItemsSource="{Binding Ergebnisse}" Style="{StaticResource ErgebnisStil}" Background="Black" MouseDoubleClick="ItemsControl_MouseDoubleClick">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<!--#endregion-->
<!--#region Tabelle -->
<TextBox Grid.Column="1" Margin="10,0" MinWidth="50" Text="{Binding Path=Name}" Style="{StaticResource PrüfungsnameStil}"/>
<TextBox Grid.Column="2" MinWidth="40" Text="{Binding Path=Folgefehler}" Style="{StaticResource FolgefehlerStil}"/>
<TextBox Grid.Column="3" MinWidth="60" Text="{Binding Path=Fehler}" Style="{StaticResource FehlerStil}" IsReadOnly="True"/>
<CheckBox Grid.Column="4" MinWidth="40" IsChecked="{Binding Status, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="5,0,0,0"/>
<!--#endregion-->
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!--#endregion-->
</Grid>
<!--#region Folgefehlerschieber -->
<Canvas>
<Thumb DragDelta="LinealVerschieben" Canvas.Left="450" Canvas.Top="0">
<Thumb.Template>
<ControlTemplate>
<Grid>
<Line X1="0" Y1="0" X2="0"
Y2="{Binding ActualHeight, Source={x:Reference ProxyElement}}"
Canvas.ZIndex="2"
Style="{StaticResource LinealStil}" Cursor="Hand">
</Line>
<Rectangle Width="11" Margin="0,0,20,0"
Height="{Binding ActualHeight, Source={x:Reference ProxyElement}}"
Style="{StaticResource AnfasserStil}" Cursor="Hand">
<Rectangle.RenderTransform>
<TranslateTransform X="-5" Y="0"/>
</Rectangle.RenderTransform>
</Rectangle>
<Label Style="{StaticResource LabelStil}" Content="{Binding Linealposition}"/>
</Grid>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Canvas>
<!--#endregion-->
</Grid>
</UserControl>
I am just testing
<CheckBox Grid.Column="4" MinWidth="40" IsChecked="{Binding Status, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="5,0,0,0"/>
This is the user control for the child page
<UserControl x:Class="Demo.View.Dashboard"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Demo.View"
xmlns:vm="clr-namespace:Demo.ViewModel"
xmlns:dt="clr-namespace:DefectTracking;assembly=DefectTrackingControl"
mc:Ignorable="d"
d:DesignHeight="900" d:DesignWidth="1600"
>
<UserControl.DataContext>
<vm:DashboardViewModel/>
</UserControl.DataContext>
<UserControl.Resources>
<vm:BindingProxy x:Key="proxy" Data="{Binding}"/>
<dt:Prüfung x:Key="www"/>
</UserControl.Resources>
<Grid Background="White">
<dt:DefectTrace Margin="0,0,-321,-91">
<dt:DefectTrace.Prüfungen>
<dt:Prüfung
Status="{Binding Path=status}" />
<dt:Prüfung Name="Stabseite" />
<dt:Prüfung Name="Stosskappe" />
<dt:Prüfung Name="Druckbild"
/>
<dt:Prüfung Name="Oberfläche"
/>
</dt:DefectTrace.Prüfungen>
</dt:DefectTrace>
<CheckBox IsChecked="{Binding state, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="100,100,100,10">Test check box</CheckBox>
</Grid>
</UserControl>
Property definition which I want to bind with checkbox but it's not propagating into a user control. If I just set true and false then it works but if I bind then it doesn't work.
Any help would be highly appreciated
I believe the problem here is
<UserControl.DataContext>
<vm:DashboardViewModel/>
</UserControl.DataContext>
because that basically means using a new instance of DashboardViewModel for this particular view, so I would assume that in your code somewhere you are using a different instance of this view model in which changing the value of Status does not really matter.
If the reason is what I think it is and you want to enhance your user comfort while developing XAML files and using this to help the compiler to know the types you can use the d:DataContext something like:
d:DataContext={x:Type vm:DashboardViewModel}

Windows Template Studio WPF UserControl not showing MetroWindow theme when changing TitleTemplate

(UPDATE: even without DEVEXPRESS controls, the same behavior is observed. So, I tested it with a couple textBlocks inside of a Grid...)
I am new to WPF development and I am using Windows Template Studio on VS 2019 (net core 3.1).
I am also using DEVEXPRESS.
I am wondering why I am losing the default MetroWindow theme in a user control when I add a custom TitleTemplate to the ShellWindow.xaml.
This is likely something very simple that I am not doing properly...
Repro steps:
1 - Create a default WPF Windows Template Studio Project. Select Navigation Pane as the Project type.
2 - Add a second blank page.
3 - Add DevExpress.WPF to the project (Not needed to duplicate).
4 - Create a simple user control
<UserControl x:Class="NoDevExpresssTitleTemplate.Views.TestUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:NoDevExpresssTitleTemplate.Views"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<dxlc:LayoutControl >
<dxlc:LayoutGroup>
<dxlc:LayoutItem Label="test1:" Width="150" VerticalAlignment="Center" Margin="20,0,0,0">
<dxe:TextEdit EditValue="Test1"/>
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="test2:" Width="150" VerticalAlignment="Center" Margin="20,0,0,0">
<d:TextBox Text="test2"/>
</dxlc:LayoutItem>
</dxlc:LayoutGroup>
</dxlc:LayoutControl>
</Grid>
5 - Use the user control on the second blank page created,
<Page
x:Class="NoDevExpresssTitleTemplate.Views.SearchPage"
Style="{DynamicResource MahApps.Styles.Page}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:properties="clr-namespace:NoDevExpresssTitleTemplate.Properties"
xmlns:views="clr-namespace:NoDevExpresssTitleTemplate.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="48" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock
Style="{StaticResource PageTitleStyle}"
Margin="{StaticResource MediumLeftMargin}"
Text="{x:Static properties:Resources.SearchPageTitle}" />
<Grid
Grid.Row="1"
Margin="{StaticResource MediumLeftRightMargin}"
Background="{DynamicResource MahApps.Brushes.Gray10}">
<!--
The Mahapps Gray10 color represents where you should place your content.
Place your content here.
-->
<views:TestUserControl></views:TestUserControl>
</Grid>
</Grid>
6 - Update the ShellWindow.xaml, including the TitleTemplate,
<controls:MetroWindow
x:Class="NoDevExpresssTitleTemplate.Views.ShellWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:properties="clr-namespace:NoDevExpresssTitleTemplate.Properties"
xmlns:templateSelectors="clr-namespace:NoDevExpresssTitleTemplate.TemplateSelectors"
Style="{StaticResource CustomMetroWindow}"
mc:Ignorable="d"
MinWidth="500"
MinHeight="350"
Title="{x:Static properties:Resources.AppDisplayName}">
<controls:MetroWindow.TitleTemplate>
<DataTemplate>
<dxlc:LayoutControl>
<dxlc:LayoutGroup Orientation="Vertical" Height="50" >
<TextBlock Text="{TemplateBinding Content}"
TextTrimming="CharacterEllipsis"
VerticalAlignment="Center"
Margin="8 -1 8 0"
FontWeight="Light"
FontSize="{DynamicResource WindowTitleFontSize}"
FontFamily="{DynamicResource HeaderFontFamily}" />
<TextBlock Text="{TemplateBinding Content}"
TextTrimming="CharacterEllipsis"
VerticalAlignment="Center"
Margin="8 -1 8 0"
FontWeight="Light"
FontSize="{DynamicResource WindowTitleFontSize}"
FontFamily="{DynamicResource HeaderFontFamily}" />
</dxlc:LayoutGroup>
</dxlc:LayoutControl>
</DataTemplate>
</controls:MetroWindow.TitleTemplate>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding LoadedCommand}" />
</i:EventTrigger>
<i:EventTrigger EventName="Unloaded">
<i:InvokeCommandAction Command="{Binding UnloadedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<controls:MetroWindow.LeftWindowCommands>
<controls:WindowCommands>
<Button
Width="{Binding ElementName=hamburgerMenu, Path=CompactPaneLength}"
AutomationProperties.Name="{x:Static properties:Resources.ShellGoBackButton}"
ToolTip="{x:Static properties:Resources.ShellGoBackButton}"
Command="{Binding GoBackCommand}">
<TextBlock
Text=""
FontSize="14"
FontFamily="Segoe MDL2 Assets"
AutomationProperties.Name="{x:Static properties:Resources.ShellGoBackButton}" />
</Button>
</controls:WindowCommands>
</controls:MetroWindow.LeftWindowCommands>
<controls:MetroWindow.Resources>
<templateSelectors:MenuItemTemplateSelector
x:Key="MenuItemTemplateSelector">
<templateSelectors:MenuItemTemplateSelector.GlyphDataTemplate>
<DataTemplate DataType="{x:Type controls:HamburgerMenuGlyphItem}">
<Grid Height="48">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
FontSize="16"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="Segoe MDL2 Assets"
Text="{Binding Glyph}"
ToolTip="{Binding Label}" />
<TextBlock
Grid.Column="1"
VerticalAlignment="Center"
FontSize="16"
Text="{Binding Label}" />
</Grid>
</DataTemplate>
</templateSelectors:MenuItemTemplateSelector.GlyphDataTemplate>
<templateSelectors:MenuItemTemplateSelector.ImageDataTemplate>
<DataTemplate DataType="{x:Type controls:HamburgerMenuImageItem}">
<Grid Height="48">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Ellipse
Grid.Column="0"
Width="24"
Height="24"
HorizontalAlignment="Center"
VerticalAlignment="Center"
ToolTip="{Binding Label}">
<Ellipse.Fill>
<ImageBrush ImageSource="{Binding Thumbnail}" />
</Ellipse.Fill>
</Ellipse>
<TextBlock
Grid.Column="1"
VerticalAlignment="Center"
FontSize="16"
Text="{Binding Label}" />
</Grid>
</DataTemplate>
</templateSelectors:MenuItemTemplateSelector.ImageDataTemplate>
</templateSelectors:MenuItemTemplateSelector>
</controls:MetroWindow.Resources>
<controls:MetroWindow.Content>
<controls:HamburgerMenu
x:Name="hamburgerMenu"
HamburgerButtonName="{x:Static properties:Resources.ShellHamburgerButtonName}"
IsPaneOpen="False"
DisplayMode="CompactInline"
ItemsSource="{Binding MenuItems}"
SelectedItem="{Binding SelectedMenuItem}"
ItemCommand="{Binding MenuItemInvokedCommand}"
ItemTemplateSelector="{StaticResource MenuItemTemplateSelector}">
<controls:HamburgerMenu.Content>
<Frame
x:Name="shellFrame"
Grid.Row="1"
NavigationUIVisibility="Hidden"
Focusable="False" />
</controls:HamburgerMenu.Content>
</controls:HamburgerMenu>
</controls:MetroWindow.Content></controls:MetroWindow>
The default Light.Blue theme/style is lost,

C# WPF App-wide DataTemplate works on one page but not on the same page in a Datagrid

I have written a DataTemplate in App.xaml.
<DataTemplate x:Key="PlayDVBViewer">
<GroupBox Header="{x:Static properties:Resources.PlayInDVBViewer}" UseLayoutRounding="True" Margin="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="{x:Static properties:Resources.ChooseDVBViewer}" Margin="5" VerticalAlignment="Center"/>
<ComboBox Grid.Row="1" ItemsSource="{Binding Clients.Items}" SelectedItem="{Binding Client}" SelectedValuePath="Name" DisplayMemberPath="Name" Margin="5" Padding="5" VerticalAlignment="Center" Background="Transparent"/>
<!--<Button Grid.Column="1" Grid.Row="1" x:Name="btnPlay" Click="BtnPlay_Click" Margin="5" Padding="5" VerticalAlignment="Center" Background="Transparent" Content="{x:Static properties:Resources.Playback}"/>-->
<Button Grid.Column="1" Grid.Row="1" Command="{Binding BtnPlayClick}" Margin="5" Padding="5" VerticalAlignment="Center" Background="Transparent" Content="{x:Static properties:Resources.Playback}"/>
</Grid>
</GroupBox>
</DataTemplate>
The template works correctly in a page. But on the same page, in a DataGrid, it doesn't work. Why?
<!--Wiedergabe Optionen -->
<GroupBox Header="{x:Static properties:Resources.Playback}" Grid.Row="1" Grid.Column="2" Margin="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ContentPresenter Grid.Row="0" ContentTemplate="{StaticResource ResourceKey=PlayDVBViewer}" Content="{Binding}"/>
</Grid>
</GroupBox>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<Grid>
<!-- Detail Grid mit den Buttons zum Abspielen -->
<Grid Grid.Row="0">
<StackPanel Orientation="Horizontal">
<GroupBox Header="{x:Static properties:Resources.Picture}" MinWidth="120" Margin="5">
<Image Height="64" Source="{Binding ImagePath, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:PageAufnahmen}}}" Margin="5"/>
</GroupBox>
<ContentPresenter ContentTemplate="{StaticResource PlayDVBViewer}"/>
</StackPanel>
</Grid>
</Grid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
Ok, I have found the error.
If you use ContentPresenter in the DataTemplate of a grid. The binding will bind to the selected item. The solution is, use the same binding, like the image in the last box, see my post above.

How to make the scrollviewer work in this scenario?

Having some problems with my MVVM Application.
So the scenario is the following:
In my MainWindow.xaml, I have a ContentControl placed in a Grid Column, its content is bind to the CurrentViewModel which will be rendered to the appropriate View (in this case, Overview.xaml).
<ContentControl Grid.Row="1" Grid.Column="1" Content="{Binding CurrentViewModel}">
Within this particular view (Overview.xaml) there are multiple UserControls placed within a StackPanel.
<ScrollViewer CanContentScroll="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible">
<StackPanel CanVerticallyScroll="True" CanHorizontallyScroll="True">
<views:DiagramView DataContext="{Binding Path=DiagramViewModel, Source={StaticResource Locator}}" />
<views:IncomeCollectionView DataContext="{Binding Path=IncomesViewModel, Source={StaticResource Locator}}" />
<views:ExpenseCollectionView DataContext="{Binding Path=ExpensesViewModel, Source={StaticResource Locator}}" />
<views:CheckCollectionView DataContext="{Binding Path=ChecksViewModel, Source={StaticResource Locator}}" />
<views:BalanceCollectionView DataContext="{Binding Path=BalancesViewModel, Source={StaticResource Locator}}" />
<views:VacationCollectionView DataContext="{Binding Path=VacationsViewModel, Source={StaticResource Locator}}" />
<views:KHCollectionView DataContext="{Binding Path=KhViewModel, Source={StaticResource Locator}}" />
<views:OctaviaCollectionView DataContext="{Binding Path=OctaviaViewModel, Source={StaticResource Locator}}" />
</StackPanel>
</ScrollViewer>
Each UserControl within this StackPanel has a very similar look (obviously there are more stuff in the XAML). There is no constant value regarding Width or Height within my application.
<ListView ItemsSource="{Binding Source={StaticResource groupedCollection}}" SelectedItem="{Binding CurrentItem}">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Items[0].CurrentCategory}" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="12" Rows="1" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style>
<Setter Property="Grid.Column" Value="{Binding GeneratedColumn}"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding EncryptedAmount}" />
<StackPanel Orientation="Horizontal">
<TextBlock Text="Got paid on " />
<TextBlock Text="{Binding Date}" />
</StackPanel>
<Button Content="details"
Command="{Binding Path=DataContext.ShowDialogCommand,
RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
CommandParameter="QuickEdit"/>
<Button Content="remove" Command="{Binding RemoveCommand}" CommandParameter="Income removed." />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The problem is that I can't seem to make the vertical scrollviewer work. It is displayed because I make it visible, but it's disabled. Obviously the StackPanel is gonna grow indefintely, but isn't there a way for it to calculate how much space is needed? Because most of the content is just cut off right now.
So I tried to put scrollviewer in every possible place, but they're all disabled.
<Style TargetType="{x:Type ContentControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<ScrollViewer>
<ContentPresenter Cursor="{TemplateBinding Cursor}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
So then I tried dropping the StackPanel implementation and tried it with a Grid.
Nope, it doesn't work either.
Obviously I'm missing some basis solution here, but just can't figure it out.
Any ideas would be appreciated, seems like a very common scenario to be honest.
Cheers
<ScrollViewer CanContentScroll="True"
VerticalScrollBarVisibility="Visible"
HorizontalScrollBarVisibility="Visible">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<views:DiagramView DataContext="{Binding Path=DiagramViewModel, Source={StaticResource Locator}}" />
<views:IncomeCollectionView Grid.Row="1" DataContext="{Binding Path=IncomesViewModel, Source={StaticResource Locator}}" />
<views:ExpenseCollectionView Grid.Row="2" DataContext="{Binding Path=ExpensesViewModel, Source={StaticResource Locator}}" />
<views:CheckCollectionView Grid.Row="3" DataContext="{Binding Path=ChecksViewModel, Source={StaticResource Locator}}" />
...etc...
</Grid>
</ScrollViewer>
Edit: The DiagramView UserControl contains the following:
<UserControl x:Class="Expense.Manager.WPF.Views.DiagramView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:pie="clr-namespace:Expense.Manager.WPF.CustomPie"
xmlns:local="clr-namespace:Expense.Manager.WPF.Shared"
mc:Ignorable="d">
<UserControl.Resources>
<local:BoolToBrushConverter x:Key="BoolToBrushConverter" />
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Income this month: " />
<TextBlock>
<TextBlock.Text>
<PriorityBinding FallbackValue="Retrieving data...">
<Binding Path="EncryptedCurrentMonthIncome" Mode="TwoWay" IsAsync="True" />
</PriorityBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
<pie:PieChart Data="{Binding PieChartIncomeData, Mode=TwoWay}" Width="250" PieWidth="130" PieHeight="130" Height="140" />
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Expenses this month: " />
<TextBlock>
<TextBlock.Text>
<PriorityBinding FallbackValue="Retrieving data...">
<Binding Path="CurrentMonthExpense" Mode="TwoWay" IsAsync="True" />
</PriorityBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
<pie:PieChart Data="{Binding PieChartExpenseData, Mode=TwoWay}" Width="250" PieWidth="130" PieHeight="130" Height="140" />
</StackPanel>
<StackPanel Grid.Column="2">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding VacationsLeft}" />
<TextBlock Text=" days left" />
</StackPanel>
<ItemsControl ItemsSource="{Binding VacationsPerYearCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Margin="5, 0, 0, 0" Height="25" Width="4" Fill="{Binding Converter={StaticResource BoolToBrushConverter}}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Bank savings:" />
<TextBlock Text="{Binding BankSavings}" />
</StackPanel>
</StackPanel>
</Grid>
IncomeCollectionView:
<UserControl x:Class="Expense.Manager.WPF.Views.IncomeCollectionView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:views="clr-namespace:Expense.Manager.WPF.Views"
mc:Ignorable="d">
<UserControl.Resources>
<CollectionViewSource x:Key="groupedCollection" IsLiveGroupingRequested="True" Source="{Binding Collection}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="CurrentCategory" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding DisplayName}" Foreground="White" FontWeight="SemiBold" Padding="5" Background="SteelBlue" />
<ListView Grid.Row="1" ItemsSource="{Binding Source={StaticResource groupedCollection}}" SelectedItem="{Binding CurrentItem}">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Items[0].CurrentCategory}" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Columns="12" Rows="1" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style>
<Setter Property="Grid.Column" Value="{Binding GeneratedColumn}"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding EncryptedAmount}" />
<TextBlock Grid.Row="1" Text="{Binding Date}" />
<Button Grid.Row="2" Content="details"
Command="{Binding Path=DataContext.ShowDialogCommand,
RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
CommandParameter="QuickEdit"/>
<Button Grid.Row="3" Content="remove" Command="{Binding RemoveCommand}" CommandParameter="Income removed." />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
and where it is used:
why is the listview not resizing itself after resizing the window itself?
<ScrollViewer CanContentScroll="True" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<views:IncomeCollectionView Grid.Row="1" DataContext="{Binding Path=IncomesViewModel, Source={StaticResource Locator}}" />
</Grid>
</ScrollViewer>
I tried dropping the StackPanel implementation and tried it with a Grid. Nope, it doesn't work either.
That's almost correct, apart from the last sentence. Using a Grid is half of the answer, because the StackPanel has no functionality to resize its items... you just need to inform the ScrollViewer when to scroll. Take this example:
<ScrollViewer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="50" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Rectangle Fill="Cyan" />
<Rectangle Grid.Row="1" Fill="Green" />
<Rectangle Grid.Row="2" Fill="Red" />
<Rectangle Grid.Row="3" Fill="Blue" />
<Rectangle Grid.Row="4" Fill="Orange" />
<Rectangle Grid.Row="5" Fill="Purple" />
<Rectangle Grid.Row="6" Fill="Yellow" />
</Grid>
</ScrollViewer>
This XAML will make the ScrollViewer ScrollBar appear (once the Window.Height is small enough), but if you remove the RowDefinition.Height values (thereby giving each row a proportion of the whole Grid.Height), you'll see your previous situation where no ScrollBar appears.
Now, none of us want to hard code constant values into our UIs, but you can do this using the Auto setting on the RowDefinition.Height properties instead. Unlike these Rectangles, your controls will all have some Height, so your solution is to set each of your Grid.RowDefinitions like this:
<RowDefinition Height="Auto" />
This will provide your controls with as much space as they need within the Grid and therefore (hopefully) they will have more Height together than the ScrollViewer and therefore the ScrollViewer will display its vertical ScrollBar.

Scrolling for WPF TabItems (not entire TabControl)

I have the following xaml:
<UserControl x:Class="MyProject.Word.Addin.Presentation.MainTaskPane"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:MyProject.Word.Addin.Presentation"
mc:Ignorable="d">
<d:UserControl.DataContext>
<local:MyProjectPaneViewModelHandler />
</d:UserControl.DataContext>
<!--<Grid>-->
<DockPanel Name="MainDockPanel" Background="red">
<local:ExToolBar DockPanel.Dock="Top" />
<Button DockPanel.Dock="Top" Click="ButtonGetHeightDimensions" Content="Show Dimensions" Height="40"></Button>
<TabControl DockPanel.Dock="Top" x:Name="TabControl1" Background="LightSkyBlue">
<TabItem x:Name="Tab1" Background="LightGreen">
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Ellipse Width="10" Height="10" Fill="DarkGray"/>
<TextBlock>Filters</TextBlock>
</StackPanel>
</TabItem.Header>
<ScrollViewer Name="ScrollViewer1" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<StackPanel Name="Tab1StackPanel" Orientation="Vertical" MaxHeight="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}, Path=ActualHeight}" >
<TextBlock FontSize="24" FontWeight="Bold" Foreground="DarkSlateGray" FontStyle="Normal">
Filters
</TextBlock>
<Button x:Name="ClearFiltersButton" Click="ClearFilters_OnClick" Background="DarkRed" Foreground="White"
FontSize="20" FontWeight="Bold" MaxWidth="124" HorizontalAlignment="Left">
Clear Filters
</Button>
<StackPanel Orientation="Horizontal">
<TextBlock>
<Run>Total Paragraphs </Run><Run Text="{Binding ResearchLanguageViewModel.TotalCount}"></Run>
</TextBlock>
</StackPanel>
<ItemsControl ItemsSource="{Binding ResearchLanguageViewModel.Filters, Mode=OneWay}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Type}"></TextBlock>
<TextBox Text="Search...."></TextBox>
<ItemsControl ItemsSource="{Binding Path=Values, Mode=OneWay}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Mode=OneWay}"></CheckBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
</TabItem>
<TabItem x:Name="Tab2">
<TabItem.Header>
<TextBlock>A 2nd Tab</TextBlock>
</TabItem.Header>
<StackPanel Orientation="Horizontal">
<TextBlock>
<Run>Mama always said lifes like a box of chocolates...</Run>
</TextBlock>
</StackPanel>
</TabItem>
</TabControl>
</DockPanel>
<!--</Grid>-->
And the following objects....
public class FilterViewModel
{
public string Type { get; set; }
public ObservableCollection<string> Values { get; set; }
}
public class ResearchLanguageViewModel
{
public int FirmCount { get; set; }
public ObservableCollection<FilterViewModel> Filters { get; set; }
}
I have binding setup using the INotifyPropertyChanged, etc... and all is working. The final issue I have is with the Scrolling of the TabItem content in my first tab. The requirements call for only the tabs with overflowing content to scroll and not the entire tab control. I.e. - the tab headers should still be viewable including controls above the tab control itself and the scroll bars should appear inside of Tab1's TabItem area. I've played with this for hours to no avail. I'm obviously doing something wrong here and could use some assistance.
A bit more detail: The binding on the CheckBox(es) / ItemControls on the Values collection can have upward of 200 - 500 controls and thus causes everything to get knocked out of wack.
you can make use of a Grid container instead of StackPanel, I attempted to make a sample for you
sample
<ScrollViewer Name="ScrollViewer1"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<Grid Name="Tab1StackPanel">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock FontSize="24"
FontWeight="Bold"
Foreground="DarkSlateGray"
FontStyle="Normal">
Filters
</TextBlock>
<Button x:Name="ClearFiltersButton"
Grid.Row="1"
Background="DarkRed"
Foreground="White"
FontSize="20"
FontWeight="Bold"
MaxWidth="124"
HorizontalAlignment="Left">
Clear Filters
</Button>
<StackPanel Orientation="Horizontal"
Grid.Row="2">
<TextBlock>
<Run>Total Paragraphs </Run><Run Text="{Binding ResearchLanguageViewModel.TotalCount}"></Run>
</TextBlock>
</StackPanel>
<ItemsControl ItemsSource="{Binding ResearchLanguageViewModel.Filters, Mode=OneWay}"
Grid.Row="3">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Type}"></TextBlock>
<TextBox Text="Search...."></TextBox>
<ItemsControl ItemsSource="{Binding Path=Values, Mode=OneWay}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Mode=OneWay}"></CheckBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</ScrollViewer>
grid with row definitions of auto height behaves same like a stack panel except the last one which uses up the remaining space.
we can adjust it further to match the exact needs

Categories