WPF How to make declaration into code? - wpf

I download a sample code from here
http://www.codeproject.com/Articles/28306/Working-with-Checkboxes-in-the-WPF-TreeView
The sample code works fine. My questions is that I want to make this part of xaml into C# code.
<Window.Resources>
<ResourceDictionary>
<!-- Load this specific theme because the Aero theme for CheckBox has issues. -->
<Style x:Key="TreeViewItemStyle" TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="True" />
<Setter Property="IsSelected" Value="{Binding IsInitiallySelected, Mode=OneTime}" />
<Setter Property="KeyboardNavigation.AcceptsReturn" Value="True" />
<Setter Property="dw:VirtualToggleButton.IsVirtualToggleButton" Value="True" />
<Setter Property="dw:VirtualToggleButton.IsChecked" Value="{Binding IsChecked}" />
</Style>
<HierarchicalDataTemplate
x:Key="CheckBoxItemTemplate"
ItemsSource="{Binding Children, Mode=OneTime}"
>
<StackPanel Orientation="Horizontal">
<!-- These elements are bound to a FooViewModel object. -->
<CheckBox
Focusable="False"
IsChecked="{Binding IsChecked}"
VerticalAlignment="Center"
/>
<ContentPresenter
Content="{Binding Name, Mode=OneTime}"
Margin="2,0"
/>
</StackPanel>
</HierarchicalDataTemplate>
</ResourceDictionary>
</Window.Resources>
Can anyone tell me how to do that?
Thanks,

Related

Hide HeaderContent from the top of a ListView

I have a
<DockPanel>
<!-- Header -->
<Button DockPanel.Dock="Top" Command="{Binding CreateAccountCommand}" Margin="{StaticResource ControlMargin}" Style="{StaticResource IconButtonStyle}">
<StackPanel>
<MahAppsIconPacks:PackIconFontAwesome Kind="Pencil" />
<TextBlock>create account</TextBlock>
</StackPanel>
</Button>
<!-- Accounts list -->
<ListView SelectionMode="Single" SelectedIndex="0" ItemsSource="{Binding AccountViewModels}" SelectedItem="{Binding SelectedItem}" Style="{StaticResource AccountsList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<LocalViews:AccountView Margin="{StaticResource ControlMargin}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListView>
</DockPanel>
It renders with a black separator on top of it, which is quite ugly. How do I hide it? I have tried setting different styles, but there is no ListViewColumnHeader.
In the live tree it shows as header content ... not separator, my bad. How do I remove it?
This doesn't work:
<Style TargetType="ListView" x:Key="AccountsList" BasedOn="{StaticResource {x:Type ListView}}">
<Style.Resources>
<Style TargetType="HeaderedContentControl">
<Setter Property="Visibility" Value="Collapsed" />
</Style>
</Style.Resources>
</Style>
Are you using any of the View capabilities of ListView? (e.g. GridView etc which I believe is the default. In which case, the separator is probably the header section, but empty). If you're not, try just using a ListBox instead. It has no header as default.
Edit: I just checked this theory, but it appears I can't reproduce your issue at all. Here's a ListBox as you've got your code (and a ListView for good measure):
<Window.Resources>
<x:Array x:Key="Items" Type="sys:String">
<sys:String>Item 1</sys:String>
<sys:String>Item 2</sys:String>
<sys:String>Item 3</sys:String>
</x:Array>
</Window.Resources>
<StackPanel Margin="20">
<TextBlock Text="ListBox:"/>
<ListBox Height="100" ItemsSource="{StaticResource Items}" BorderBrush="Transparent">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListBox>
<TextBlock Text="ListView:"/>
<ListView Height="100" ItemsSource="{StaticResource Items}" BorderBrush="Transparent">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListView>
</StackPanel>
It may be the different themes on Windows 7 however, I'm using Windows 10.
I believe this is a result of the MahApps template. It's not the default behaviour of a standard WPF ListView.
You would have to adjust the MahApps template to get rid of it.
Something like this:
<Style TargetType="{x:Type ListView}" BasedOn="{StaticResource {x:Type ListView}}">
<Setter Property="BorderThickness" Value="0" />
</Style>
The MahApps code and resources are all open source. I think the particular problem you are having is driven by the BorderThickness setter here:
https://github.com/MahApps/MahApps.Metro/blob/develop/src/MahApps.Metro/MahApps.Metro/Styles/Controls.ListView.xaml
<Style x:Key="MetroListView" TargetType="{x:Type ListView}">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="AlternationCount" Value="2" />
<Setter Property="Background" Value="{DynamicResource WhiteBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource BlackBrush}" />
<Setter Property="BorderThickness" Value="0 1 0 0" />

Optionally apply multiple styles

Let's say I have a extremly simplified xaml as follows:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="converter" />
<Style TargetType="FrameworkElement" x:Key="maybeCollapsed">
<Setter Property="Visibility" Value="{Binding Collapsed, Converter={StaticResource converter}}" />
</Style>
</UserControl.Resources>
<StackPanel>
<Label FontWeight="Bold" Content="Header" x:Name="Header" />
<TextBox Text="Name" Style="{StaticResource maybeCollapsed}" />
<TextBox Text="{Binding Name1}" Style="{StaticResource maybeCollapsed}"/>
</StackPanel>
</UserControl>
How could I apply a second style to all elements that use the maybeCollapsed-style, setting the IsTabStopto False? I cannot do this in the style itself, as IsTabStop is not a member of FrameworkElements.
Use Control.IsTabStop instead
<Style TargetType="FrameworkElement" x:Key="maybeCollapsed">
<Setter Property="Visibility" Value="{Binding Collapsed, Converter={StaticResource converter}}" />
<Setter Property="Control.IsTabStop" Value="False" />
</Style>

WPF ContentPresenter only showing first item in list

I am trying to create a WPF application where I have a StackPanel that shows a list of accounts. There is an Account object in the code behind for each account, stored in a List structure. I want to databind this to my WPF, but I don't want a listbox.
Instead, I defined a template for how each account summary should appear. I then want to stack these in a StackPanel and call it a day.
The problem is that the Data Binding only takes the first item from the list and that's it. How to I bind it so that this effectively creates a little stacked list of nicely formatted chunks of data?
Here is the relevant WPF code:
<StackPanel Name="sp_AccountList" Margin="0,0,0,0" VerticalAlignment="Top">
<StackPanel.Resources>
<svc:AccountBalanceColorConverter x:Key="accountColorConverter" />
<Style x:Key="AccountSummaryBackgroundGradient" TargetType="{x:Type StackPanel}">
<!-- nice formatting code here -->
</Style>
<Style x:Key="AccountSummaryNameStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Padding" Value="10,0,0,0" />
<Setter Property="FontSize" Value="18" />
<Setter Property="Height" Value="20" />
<Setter Property="FontFamily" Value="Cambria" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Background" Value="Transparent" />
</Style>
<Style x:Key="AccountSummaryBalanceStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Padding" Value="10,0,0,0" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Height" Value="20" />
<Setter Property="FontFamily" Value="Cambria" />
<Setter Property="Background" Value="Transparent" />
</Style>
<ObjectDataProvider x:Key="accounts"
ObjectType="{x:Type svc:AccountService}"
MethodName="ListAccounts" />
<DataTemplate x:Key="AccountSummaryLayout">
<StackPanel Orientation="Vertical" Style="{StaticResource AccountSummaryBackgroundGradient}">
<TextBlock Text="{Binding Path=Name}" Style="{StaticResource AccountSummaryNameStyle}" />
<StackPanel Orientation="Horizontal">
<TextBlock Foreground="{Binding Path=TotalAccountBalance, Converter={StaticResource accountColorConverter} }" Text="{Binding Path=TotalAccountBalance, Mode=OneWay}" Style="{StaticResource AccountSummaryBalanceStyle}" />
<TextBlock Foreground="{Binding Path=AvailableAccountBalance, Converter={StaticResource accountColorConverter} }" Text="{Binding Path=AvailableAccountBalance, Mode=OneWay}" Style="{StaticResource AccountSummaryBalanceStyle}" />
</StackPanel>
</StackPanel>
</DataTemplate>
</StackPanel.Resources>
<StackPanel Orientation="Vertical">
<ContentPresenter x:Name="AccountSummaryPresenter" ContentTemplate="{StaticResource AccountSummaryLayout}" Content="{DynamicResource accounts}" />
</StackPanel>
</StackPanel>
StackPanel does not have an ItemsSource property, its children controls are not databindable.
What you can do is create an ItemsControl which uses a StackPanel as its Itemshost.
<ScrollViewer>
<ItemsControl ItemsSource="{Binding Source={StaticResource accounts}}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel IsItemsHost="True" Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
...
</ItemsControl.ItemTemplate>
</ItemsControl>
<ScrollViewer>

WPF Style Triggers in DataTemplate

i hope you can help me. I got following Code in the Resources:
<UserControl.Resources>
<BitmapImage x:Key="img_src_lock" UriSource="/EEBase;component/Images/Lock_24x32.png" />
<BitmapImage x:Key="img_src_unlock" UriSource="/EEBase;component/Images/Unlock_24x32.png" />
<Style TargetType="{x:Type ToggleButton}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Value="True">
<Setter Property="Content">
<Setter.Value>
<Image Source="{StaticResource img_src_lock}" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Value="False">
<Setter Property="Content">
<Setter.Value>
<Image Source="{StaticResource img_src_unlock}" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
<!-- TypeComboTemplateCollapsed -->
<DataTemplate x:Key="TypeComboTemplateCollapsed">
<TextBlock
Text="{Binding Path=Text, Mode=OneWay}"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="5,0,0,5"
/>
</DataTemplate>
<!-- TypeComboTemplateExpanded -->
<DataTemplate x:Key="TypeComboTemplateExpanded">
<TextBlock
Text="{Binding Path=Text, Mode=OneWay}"
VerticalAlignment="Center"
Margin="5,0,0,5"
/>
</DataTemplate>
<!-- EditCircleTemplate -->
<DataTemplate x:Key="EditCircleTemplate">
<!-- some content here, no ToggleButton -->
</DataTemplate>
<!-- EditRectangleTemplate -->
<DataTemplate x:Key="EditRectangleTemplate">
<!-- some other content here, including the ToggleButtons -->
<ToggleButton
IsChecked="{Binding Path=BaseLocked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
Margin="5"
/>
<ToggleButton
IsChecked="{Binding Path=HeightLocked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
Margin="5"
/>
</DataTemplate>
</UserControl.Resources>
To me that looks all correct.
Now, the problem is:
When i do the following, an exceptions occurs:
Specified element is already the logical child of another element. Disconnect it first.
1. load the control, selected type is CIRC
2. change the dropdown to select RECT (template triggers and togglebuttons are shown correctly)
3. change the dropdown back to CIRC
--> now the Exception occurs.
4. if i ignore the exception, the template "EditCircleTemplate" does not get loaded, and the normal ToString of the model object gets displayed.
Additional info:
originally there are 4 different types in the WPF, two of them with ToggleButtons (that's why i use templates). I cut them out, they dont differ really. But what i found out using all 4 templates is that the error does not occur when switching to a new Template, but when unloading a template with the toggle buttons. Which is kinda strange.
Also if i remove the DataTriggers for the ToggleButtons everything works like a charm.
The Exception comes from the XAML-Interpreter, so the Stacktrace is not useful at all.
Can anyone give me a hint what i am doing wrong?
Edit:
oops, i guess i forgot the content code:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="160"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<ComboBox
Margin="5"
Grid.Row="0"
Grid.Column="0"
ItemsSource="{Binding Path=PossibleTypes, Mode=OneTime}"
SelectedItem="{Binding Path=SelectedType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<ContentControl x:Name="content" Content="{Binding}" ContentTemplate="{StaticResource TypeComboTemplateExpanded}"/>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ComboBoxItem}}" Value="{x:Null}">
<Setter TargetName="content" Property="ContentTemplate" Value="{StaticResource TypeComboTemplateCollapsed}"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ContentControl
Grid.Column="0"
Grid.Row="1"
Grid.ColumnSpan="2"
Content="{Binding Mode=OneWay}">
<ContentControl.ContentTemplate>
<DataTemplate >
<ContentControl
Name="inputContent"
Content="{Binding Mode=OneWay}"
ContentTemplate="{x:Null}"
/>
<DataTemplate.Triggers>
<DataTrigger
Binding="{Binding Path=SelectedType.Type, Mode=OneWay}"
Value="CIRC">
<Setter
TargetName="inputContent"
Property="ContentTemplate"
Value="{StaticResource EditCircleTemplate}"
/>
</DataTrigger>
<DataTrigger
Binding="{Binding Path=SelectedType.Type, Mode=OneWay}"
Value="RECT">
<Setter
TargetName="inputContent"
Property="ContentTemplate"
Value="{StaticResource EditRectangleTemplate}"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
</Grid>
Edit2/Solution:
I just found a workaround - it just does not satisfy me:
Instead of putting the style in the UserControl.Resources, which for me would be the more clean and intuitive solution, i have to set the style with the triggers on each ToggleButton separately.
So removing the and adding following code to each ToggleButton did the trick:
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Value="True" >
<Setter Property="Content">
<Setter.Value>
<Image Source="{StaticResource img_src_lock}" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Value="False">
<Setter Property="Content">
<Setter.Value>
<Image Source="{StaticResource img_src_unlock}" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
The big question still persists: WHY?
The problem is that if you create an Image in a style there is only one instance, so as soon as multiple controls use the style there is going to be a fight over this one instance which can only be owned by one control.
The easiest solution to this is placing the Style in a resource and setting x:Shared to false, that way a copy of the style is used whereever referenced.
Why do you need to create BitmapImages and set them as Source to your Content Images in Triggers? Why arent you using the URI source to Images directly?
<Style TargetType="{x:Type ToggleButton}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Value="True">
<Setter Property="Content">
<Setter.Value>
<Image Source="/EEBase;component/Images/Lock_24x32.png" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Value="False">
<Setter Property="Content">
<Setter.Value>
<Image Source="/EEBase;component/Images/Unlock_24x32.png" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
Let me know if this helps.

Help Creating a Style for a ListBoxItem

I am new to styles and need help to create a style for a ListBoxItem that will give the item a transparent background then have the Font turn Gold when hovered over. It should not change the color when clicked and return to normal when the mouse moves off. It must still pass the selected object to the PreviewMouseRightButtonDown event for the ListBox
I currently use a default dictionary from REUXABLES THEMES, but it is way to much coloring for this portion of the display on the application.
Thanks,
<DataTemplate x:Key="ItemsTemplate">
<StackPanel Orientation="Vertical"
Margin="0,5,0,5"
Width="{Binding
Path=ActualWidth,
RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType={x:Type ScrollContentPresenter}}}" MaxWidth="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ScrollViewer}}, Path=ViewportWidth}" >
<TextBlock VerticalAlignment="Top" TextWrapping="Wrap" FontSize="14" Text="{Binding Path=CID}" />
<StackPanel Orientation="Horizontal" Margin="0,5,0,0" >
<TextBlock>
<Label Foreground="{DynamicResource DisabledForegroundBrush}" >Posted by</Label>
<Label Foreground="{DynamicResource DisabledForegroundBrush}" VerticalContentAlignment="Top" Content="{Binding Path=ACID}" />
</TextBlock>
<TextBlock>
<Label Foreground="{DynamicResource DisabledForegroundBrush}" Margin="3,0,0,0">at</Label>
<Label Foreground="{DynamicResource DisabledForegroundBrush}" Margin="3,0,3,0" VerticalContentAlignment="Top" Content="{Binding Path=Type}" />
</TextBlock>
<TextBlock>
<Label Foreground="{DynamicResource DisabledForegroundBrush}">(</Label>
<Label Foreground="{DynamicResource DisabledForegroundBrush}" VerticalContentAlignment="Top" Content="{Binding Path=Route}" />
<Label Foreground="{DynamicResource DisabledForegroundBrush}">)</Label>
</TextBlock>
</StackPanel>
</StackPanel>
</DataTemplate>
<Style x:Key="ItemsListBox" TargetType="{x:Type ListBoxItem}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="Background" Value="{DynamicResource Transparent}"/>
<Setter Property="BorderBrush" Value="{DynamicResource Transparent}"/>
<Setter Property="BorderBrush" Value="{DynamicResource Transparent}"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
</Style>
<ListBox x:Name="ListViewFlightPlans" Grid.Column="0" ItemTemplate="{DynamicResource ItemsTemplate}"
MaxWidth="800" ScrollViewer.HorizontalScrollBarVisibility="Disabled" BorderBrush="Black" BorderThickness="2,0,0,1">
</ListBox>
Dave
Unfortunately changing BorderBrush for the ListBoxItem won't have your desired effect, since the Border with the selection highlight is internal to the ControlTemplate of the ListBoxItem.
Instead, you can add a new Brush resource with the key of SystemColors.HighlightBrushKey, this is the key that the ListBoxItem uses for setting the selection highlight color.
The inactive selection brush uses the key of SystemColors.ControlBrushKey, so if you override both of these with a transparent Brush you're guaranteed not to have any selection color. You can read more about it in this article.
Here's an example with everything but your DataTemplate:
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid.Resources>
<x:Array x:Key="data" Type="{x:Type sys:String}">
<sys:String>a </sys:String>
<sys:String>bb</sys:String>
<sys:String>ccc</sys:String>
<sys:String>dddd</sys:String>
</x:Array>
</Grid.Resources>
<ListBox ItemsSource="{StaticResource data}">
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent"/>
</Style.Resources>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Black"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Gold"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.Resources>
</ListBox>
</Grid>

Resources