Can't change blue background in XAML Accordion - wpf

I am trying to use the accordion control in XAML but am unable to change the dark blue background that is used as default. I've manage to stumble upon a few other people having the same problem but with no solutions posted. The only answer I have found thus far involves using Expression Studio, but I unfortunately do not own a copy.
See below the designer code, there's not a whole lot there at the moment, I've tried setting the background property on each element but get no result on any of them.
<Window x:Class="Test.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="289"
Width="500"
xmlns:my="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Layout.Toolkit">
<Grid>
<my:Accordion HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<my:AccordionItem x:Name="item1" Header="Item 1">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
</Grid>
</my:AccordionItem>
<my:AccordionItem x:Name="item2" Header="Item 2">
</my:AccordionItem>
<my:AccordionItem x:Name="item3" Header="Item 3">
</my:AccordionItem>
</my:Accordion>
</Grid>
</Window>

Take a look at this MSDN Forum thread of someone having the same problem. Also be aware this control is of Preview quality which according to CodePlex is equivalant to an Alpha release.
From above link:
The key part is binding to the actual outer grid. For some reason, the accordion item isn't providing a width/height for the inner grid to stretch to, so you have to bind it to something "higher up" so to speak.
I tested it and it does work, It does give designer errors of Object reference not set to an instance of an object It does compile and run though.
<Grid>
<my:Accordion HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<my:AccordionItem x:Name="item1" Header="Item 1">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="White"
Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}, Path=ActualWidth}"
Height="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Grid}}, Path=ActualHeight}">
</Grid>
</my:AccordionItem>
<my:AccordionItem x:Name="item2" Header="Item 2">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="White"
Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}, Path=ActualWidth}"
Height="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Grid}}, Path=ActualHeight}">
</Grid>
</my:AccordionItem>
<my:AccordionItem x:Name="item3" Header="Item 3">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="White"
Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}, Path=ActualWidth}"
Height="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Grid}}, Path=ActualHeight}">
</Grid>
</my:AccordionItem>
</my:Accordion>
</Grid>

Related

Binding to the Title of a Window does not always work

I need to databind two TextBlocks to the Window.Title property. The first one works via:
RelativeSource FindAncestor, AncestorType=Window}"
But the second one does not (it's deeply nested within a button ToolTip).
How can I change the second one to make it also display the Title of the Window?
<Window ...>
<Border ...>
<Grid ...>
<Grid ...>
<!-- TEXTBLOCK BELOW WORKS -->
<TextBlock Grid.Column="2" Text="{Binding Title, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
HorizontalAlignment="Stretch" VerticalAlignment="Center" Foreground="White" FontSize="18px" FontStretch="UltraExpanded" />
<Button Grid.Column="3" HorizontalAlignment="Right" VerticalAlignment="Stretch"
Background="Transparent" BorderBrush="Transparent" Foreground="Transparent"
ToolTipService.InitialShowDelay="0" ToolTipService.BetweenShowDelay="0" ToolTipService.ShowDuration="60000">
<Button.ToolTip>
<ToolTip x:Name="helpButtonTooltip" Width="240" ToolTipService.InitialShowDelay="0">
<!-- TEXTBLOCK BELOW DOES NOT WORK; HOW CAN I MAKE IT WORK? -->
<TextBlock Text="{Binding Title, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
HorizontalAlignment="Stretch" VerticalAlignment="Center" Foreground="White" FontSize="18px" FontStretch="UltraExpanded" />
The tool tip is displayed in a popup and is not part of the same visual tree as the button or your window. Consequently, RelativeSource and ElementName bindings do not work.
What you can do is bind the window title to the Tag property of your button and then bind the Text of the tool tip TextBlock to the Tag property of the PlacementTarget (which is the button).
<Button Tag="{Binding Title, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}">
<Button.ToolTip>
<ToolTip>
<TextBlock Text="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource AncestorType={x:Type ToolTip}}}"/>
</ToolTip>
</Button.ToolTip>
</Button>

WPF DataTemplate previewmouseleftbuttonup not working

I have Listbox with ListItemTemplate. There are two commands I want attach with each list item.
1) PreviewMouseLeftButtonDown : I use this even when for drag and drop functionality. user press button event gets fired and I came to know how many items user has selected for dragging.
2) PreviewMouseLeftButtonUp: I want to use this when user release mouse from list item. (But issue is this even never gets fired. It seems like 1st event taking control of both.
Here is my code. Pls help.
<DataTemplate x:Key="ListItemTemplate">
<Grid Margin="0" Width="58" Height="58" x:Name="OuterGrid">
<Border x:Name="OuterBorder" BorderBrush="{DynamicResource ContentToGreyedOutBrush}" BorderThickness="0" Margin="0" Background="Transparent" Grid.Column="0" Grid.Row="0"
ClipToBounds="True" CornerRadius="0">
<Border x:Name="InnerBorder" BorderBrush="Transparent" BorderThickness="1" Margin="0" Background="Transparent" CornerRadius="0">
<Grid>
<Image Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" Source="{Binding Path=FileName,Converter={StaticResource FileNameImageConverter}}"
Width="50" Height="50">
</Image>
<ToggleButton x:Name="zoomButton" Grid.Column="0" Grid.Row="0" Margin="0" HorizontalAlignment="Right" HorizontalContentAlignment="Right" VerticalAlignment="Bottom"
VerticalContentAlignment="Bottom" Background="Transparent" Cursor="Hand" Template="{StaticResource ZoomTemplate}" Width="20" Height="20" Visibility="Collapsed">
</ToggleButton>
</Grid>
</Border>
</Border>
<ac:CommandBehaviorCollection.Behaviors>
<ac:BehaviorBinding Event="PreviewMouseLeftButtonDown" Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}},Path=DataContext.DragItemSelectedCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}"/>
<ac:BehaviorBinding Event="PreviewMouseLeftButtonUp" Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}},Path=DataContext.MouseUPCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}"/>
</ac:CommandBehaviorCollection.Behaviors>
</Grid>
</DataTemplate>
It looks like you're trying to do dragging of the item to a different location outside the original bounds. In this case the up event would be firing on the new control over which the mouse is located when it is released, not the control that you started dragging. To make this work you need to make sure to capture the mouse when starting a drag operation.

ScrollViewer content is scrolling over other parts of window

I have the following as part of my XAML:
<DockPanel>
<ToolBar Name="toolbar1" DockPanel.Dock="Top" Height="41" Background="#FFA5D95A">
//other controls
</ToolBar>
<ScrollViewer>
<ListBox Name="listBox1" ItemsSource="{Binding ElementName=This, Path=Items}"
ItemTemplateSelector="{StaticResource entryItemTemplateSelector}">
<ListBox.Template>
<ControlTemplate>
<WrapPanel IsItemsHost="True" />
</ControlTemplate>
</ListBox.Template>
</ListBox>
</ScrollViewer>
</DockPanel>
I want the scrool bar to move the items in the ListBox just to the top of the WrapPanel, and then to stop showing them when they get to the top; in stead, these items scroll into the ToolBar at the top.
What am I doing wrong?
Note: Haing been asked, here are the DataTemplates I currently have; EntryItemHost is a type derived from WindowsFormsHost.
<DataTemplate x:Key="folderTemplate">
<my:EntryItemHost Item="{Binding}"
Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=my:MainWindow, AncestorLevel=1}, Path=Background}"
DoubleClick="FolderDoubleClick" />
</DataTemplate>
<DataTemplate x:Key="imageTemplate">
<my:EntryItemHost Item="{Binding}"
Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=my:MainWindow, AncestorLevel=1}, Path=Background}" />
</DataTemplate>
Instead of setting ListBox Template set the ItemsPanel and remove the ScrollViewer
sample
<DockPanel>
<ToolBar Name="toolbar1"
DockPanel.Dock="Top"
Height="41"
Background="#FFA5D95A">
//other controls
</ToolBar>
<ListBox Name="listBox1" ItemsSource="{Binding ElementName=This, Path=Items}"
ItemTemplateSelector="{StaticResource entryItemTemplateSelector}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Width="{Binding ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType=ContentPresenter}}" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</DockPanel>
notice that I have replaced the template with ItemsPanel and restricted the width to the listbox
I made this based on the assumptions, let me know is this not what you are looking for

Modifying TabControl's header

So I'm adding my views directly to the TabControl's Items collection at runtime (instead of creating TabItems around them and addings those TabItems to TabControl). The views expose a property (wrapper around a ViewModel property of the same name) named HasChanges that I want to bind to TabItem's Header to show a Asterisk (*) sign to identify tabs with unsaved changes, just like VS does. I have already tried using DataTemplates but am having trouble accessing the view object in the DataTemplate. What's the correct way of doing this? Here's one of my several attempts:
<TabControl.ItemTemplate>
<DataTemplate DataType="UserControl">
<StackPanel Orientation="Horizontal" Margin="0" Height="22">
<TextBlock VerticalAlignment="Center" Text="{Binding HeaderText, RelativeSource={RelativeSource AncestorType=UserControl}}" />
<TextBlock Text="*" Visibility="{Binding HasChanges, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource B2VConverter}}" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
Note that I'm trying two different binding methods for the two TextBlocks, none of which is working. My views inherit from UserControl and expose properties HasChanges and HeaderText.
OK. I solved it myself. For anyone else trying to implement a VS-like Close button and unsaved changes asterisk, here's the template:
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="HeaderTemplate" >
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0" Height="22">
<TextBlock VerticalAlignment="Center" Text="{Binding RelativeSource={RelativeSource AncestorType=TabItem}, Path=Content.HeaderText}" />
<TextBlock Text=" *" ToolTip="Has unsaved changes" Visibility="{Binding Content.DataContext.HasChanges, RelativeSource={RelativeSource AncestorType=TabItem}, Converter={StaticResource B2VConverter}}" />
<Button Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" Width="18" Height="18"
Margin="6,0,0,0" Padding="0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Center"
Command="{Binding DataContext.TabClosingCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}"
VerticalAlignment="Center" Focusable="False">
<Grid Margin="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Line StrokeThickness="3" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Stroke="Gray" X1="1" Y1="1" X2="9" Y2="9" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Line StrokeThickness="3" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Stroke="Gray" X1="1" Y1="9" X2="9" Y2="1" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Button>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.ItemContainerStyle>
Results in an elegant drawing-based button with a flat-look. Your View must implement Boolean HasChanges and HeaderText properties, plus you need to define a BooleanToVisibilityConverter in your resources section, named B2VConverter.

ListView: define ItemsPanelTemplate in resource dictionary

I have a ListView which layout looks like a Windows Explorer view (icon + some details), bound to a list somewhere in the ViewModel.
My aim here is to be able to switch between explorer view or classic view whenever we want.
I could define an ItemsPanelTemplate doing exactly the work to display correctly the layout, directly in the ListView.ItemsPanel field. Now, I'd like to define it in the resources so that I'll be able to use it in different views, and especially in one control, the user should have the choice between Explorer view or classic list view (the default rendering for a list)
How'd you do that? I cannot define any ItemsPanelTemplate in my ResourceDictionary, and if I define a DataTemplate it is not compatible (while I thought that following pure logic, ItemsPanelTemplate should inherit from DataTemplate, but it actually doesn't look like so).
Code snippet for the actual list:
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel
Width="{Binding (FrameworkElement.ActualWidth),
RelativeSource={RelativeSource
AncestorType=ScrollContentPresenter}}"
ItemWidth="{Binding (ListView.View).ItemWidth,
RelativeSource={RelativeSource AncestorType=ListView}}"
ItemHeight="{Binding (ListView.View).ItemHeight,
RelativeSource={RelativeSource AncestorType=ListView}}"
/>
<!--
MinWidth="{Binding ItemWidth, RelativeSource={RelativeSource Self}}"
-->
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel
Orientation="Horizontal"
Height="Auto"
Width="150" >
<Image
Source="{Binding Path=Appli.AppType, Converter={StaticResource TypeToIconConverter}}"
Margin="5"
Height="50"
Width="50" />
<StackPanel
VerticalAlignment="Center"
Width="90" >
<TextBlock
Text="{Binding Path=Appli.AppName}"
FontSize="13"
HorizontalAlignment="Left"
TextWrapping="WrapWithOverflow"
Margin="0,0,0,1" />
<TextBlock
Text="{Binding Path=Appli.AppType}"
FontSize="9"
HorizontalAlignment="Left"
Margin="0,0,0,1" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
Keeping the ItemTemplate in a static resource was easy to do, but now I can't do anything with the ItemsPanelTemplate...
Any ideas? I'm using MVVM so I'm trying ideally not to use code-behind if possible
You would use a style for the whole ListView for that. So you would do:
<Grid.Resources>
<Style x:Key="ListViewStyle" TargetType="ListView">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel
Width="{Binding (FrameworkElement.ActualWidth), RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"
ItemWidth="{Binding (ListView.View).ItemWidth, RelativeSource={RelativeSource AncestorType=ListView}}"
ItemHeight="{Binding (ListView.View).ItemHeight, RelativeSource={RelativeSource AncestorType=ListView}}" />
<!--
MinWidth="{Binding ItemWidth, RelativeSource={RelativeSource Self}}"
-->
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<ListView
SelectionMode="Single"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Bottom"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ItemsSource="{Binding ListUserApps, UpdateSourceTrigger=PropertyChanged}"
SelectedIndex="{Binding SelectedUserApp, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Background="White"
Style="{StaticResource ListViewStyle}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel
Orientation="Horizontal"
Height="Auto"
Width="150">
<Image
Source="{Binding Path=Appli.AppType, Converter={StaticResource TypeToIconConverter}}"
Margin="5"
Height="50"
Width="50"/>
<StackPanel
VerticalAlignment="Center"
Width="90">
<TextBlock
Text="{Binding Path=Appli.AppName}"
FontSize="13"
HorizontalAlignment="Left"
TextWrapping="WrapWithOverflow"
Margin="0,0,0,1" />
<TextBlock
Text="{Binding Path=Appli.AppType}"
FontSize="9"
HorizontalAlignment="Left"
Margin="0,0,0,1" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
If you want the user then be able to switch between explorer and classic view, just define a second Style and switch the style of the listview. This can be done for example with some VisualStates and a 'DataStateBehavior'.
Alternatively you could create a style with some DataTriggers and Setters for the individual ItemsPanels.

Resources