I'm creating a ListBox in my C# code, and I need to write this code in C#, although I'm not exactly sure how to do it,
http://smehrozalam.wordpress.com/2011/01/31/silverlight-and-wpf-how-to-make-items-stretch-horizontally-in-a-listbox/
<Grid>
<Grid.Resources>
<Style x:Key="ListBoxItemStyle" TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</Grid.Resources>
<ListBox Margin="100" ItemsSource="{Binding MyList}"
ItemContainerStyle="{StaticResource ListBoxItemStyle}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding}"
Background="LightYellow"
TextWrapping="Wrap" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
More specificly, how do I write this in C#
<Style x:Key="ListBoxItemStyle" TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
And
ItemContainerStyle="{StaticResource ListBoxItemStyle}"
You can create the style via:
Style style = new Style(typeof(ListBoxItem));
style.Setters.Add(new Setter(Control.HorizontalContentAlignment, HorizontalAlignment.Stretch));
You can then set this via:
listBox.ItemContainerStyle = style;
The answer posted by Reed Copsey will work.
A naive alternative (though honestly likely more "efficient," since it's explicit) is to set the HorizontalContentAlignment property of your ListBoxItem objects to HorizontalAlignment.Stretch, when you construct them (if you're also constructing them in code).
ListBoxItem i = new ListBoxItem { HorizontalContentAlignment = HorizontalAlignment.Stretch };
Related
I am trying to learn something about WPF and I am quite amazed by its flexibility.
However, I have hit a problem with Styles and DataTemplates, which is little bit confusing.
I have defined below test page to play around a bit with styles etc and found that the Styles defined in <Page.Resources> for Border and TextBlock are not applied in the DataTemplate, but Style for ProgressBar defined in exactly the same way is applied.
Source code (I just use Kaxaml and XamlPadX to view the result)
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<Style TargetType="{x:Type Border}">
<Setter Property="Background" Value="SkyBlue"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="CornerRadius" Value="5"/>
</Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontWeight" Value="Bold"/>
</Style>
<Style TargetType="{x:Type ProgressBar}">
<Setter Property="Height" Value="10"/>
<Setter Property="Width" Value="100"/>
<Setter Property="Foreground" Value="Red"/>
</Style>
<XmlDataProvider x:Key="TestData" XPath="/TestData">
<x:XData>
<TestData xmlns="">
<TestElement>
<Name>Item 1</Name>
<Value>25</Value>
</TestElement>
<TestElement>
<Name>Item 2</Name>
<Value>50</Value>
</TestElement>
</TestData>
</x:XData>
</XmlDataProvider>
<HierarchicalDataTemplate DataType="TestElement">
<Border Height="45" Width="120" Margin="5,5">
<StackPanel Orientation="Vertical" Margin="5,5" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock HorizontalAlignment="Center" Text="{Binding XPath=Name}"/>
<ProgressBar Value="{Binding XPath=Value}"/>
</StackPanel>
</Border>
</HierarchicalDataTemplate>
</Page.Resources>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<StackPanel Orientation="Vertical" VerticalAlignment="Center">
<Border Height="45" Width="120" Margin="5,5">
<StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock HorizontalAlignment="Center" Text="Item 1"/>
<ProgressBar Value="25"/>
</StackPanel>
</Border>
<Border Height="45" Width="120" Margin="5,5">
<StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock HorizontalAlignment="Center" Text="Item 2"/>
<ProgressBar Value="50"/>
</StackPanel>
</Border>
</StackPanel>
<ListBox Margin="10,10" Width="140" ItemsSource="{Binding Source={StaticResource TestData}, XPath=TestElement}"/>
</StackPanel>
</Page>
I suspect it has something to do with default styles etc, but more puzzling is why some Styles are applied and some not. I cannot find an easy explanation for above anywhere and thus would like to ask if someone would be kind enough to explain this behaviour in lamens' terms with possible links to technical description, i.e. to MSDN or so.
Thanks in advance for you support!
I discovered a simple workaround for this. For any elements that are not able to search outside the data template encapsulation boundary (i.e. are not being implicitly styled), you can just declare an empty style within the data template for that element type and use the BasedOn attribute of the style to find the correct implicit style outside the data template to apply.
In the example below, the TextBox is able to search outside the data template encapsulation boundary (because it inherits from Control?), but the TextBlock is not able to, so I declare the empty style for it which can search outside the data template.
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}" />
</DataTemplate.Resources>
<DockPanel>
<TextBlock Text="{Binding Name}" />
<TextBox Text="{Binding Value}" />
</DockPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
This is actually by design. Elements that do not derive from Control will not pick up implicit Styles, unless they are in the application resources.
This link explains this in more detail, or you can view the Connent bug report.
I've looked into this also, and I personally think it's a bug. I've noticed that the style is set if you name your styles like so:
<Style x:Key="BorderStyle" TargetType="{x:Type Border}">
etc...
and explicitly set your DataTemplate to use those styles:
<HierarchicalDataTemplate DataTemplate="TestElement">
<Border Height="45" Width="120" Margin="5,5", Style="{StaticResource BorderStyle}">
I think that it's possible that for DataTemplates (and maybe ControlTemplates), they default to having a null style, unless you explicitly set them.
That to me is not meant to happen - it's not a logical way of WPF working...
This is because ListBox is a logical parent of your datatemplate items, now remember, all properties those are "inheritable" like font, forecolor etc, are derived from the logical parent and ListBox already overrides it in its own default style, thats why this will not work. However in this case, you can use named styles as Mr. Dave has suggested, but I think if it does not work then this is a known problem in case of List Box etc, you can refere to my question here, i had similar problem in listbox, and the answers in my question are in more detail.
I'm Building a Win 10 UWP app. I have a ListView as per the below xaml, which is the content of a Button.Flyout. It is essentially the same as the standard ListView control, but provides a way for me to bind to the IsSelected property of the particular item. I've added the implementation for completeness. When MinWindowWitdth is 720, the placement mode is changed to Right. Whilst in this state, the ListViewItem stretches to fill the ListView. When not in this state (default), it is in Placement.Full, and the ListViewItem doesn't stretch to the entire ListView, which does seem to stretch to fill of the Flyout, as the VerticalScrollBar is visible against the right hand edge of the Flyout.
From what I could investigate, setting the ListView.ItemContainerStyle with HorizontalContentAlignment.Stretch should have achieved the outcome, however I am left with content that only stretches about half way across and I can't figure out why.
I notice that he CommandBar is included in the scrollable content in the full screen Flyout, however, when in Placement.Right it is not (which is the intended design). So it appears that Full is causing the Flyout to create a ScrollViewer and disregard the ListView.HorizontalAlignment.Stretch property. Is there a way to get around this?
xaml;
<Button.Flyout>
<Flyout x:Name="RulesListFlyout" Placement="Full">
<RelativePanel HorizontalAlignment="Stretch">
<commontools:ListViewWithSelectedItems x:Name="RulesListForInclusion" ItemsSource="{Binding AllRulesForInclusion}" SelectionMode="Multiple" IsMultiSelectCheckBoxEnabled="True"
RelativePanel.Above="RulesCommandB" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate x:DataType="ListViewItem">
<RelativePanel Margin="12,0" HorizontalAlignment="Stretch">
<TextBlock x:Name="Title" Text="{Binding StoredDataObject.Title}" RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignTopWithPanel="True" RelativePanel.AlignRightWithPanel="True"/>
<TextBox x:Name="Variable" Text="{Binding InputVariable, Mode=TwoWay}" Width="50" AcceptsReturn="False" RelativePanel.Below="Title"
Visibility="{Binding ShowVariableBox, Converter={StaticResource TrueToVis}, Mode=TwoWay}"/>
</RelativePanel>
</DataTemplate>
</ListView.ItemTemplate>
</commontools:ListViewWithSelectedItems>
<CommandBar x:Name="RulesCommandB" Grid.Row="1" RelativePanel.AlignBottomWithPanel="True" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignRightWithPanel="True">
<AppBarButton Icon="Accept" Label="Accept" Command="{Binding CommandSetIncludedRules}" Click="SetSpecialRuleFlyoutButton_Click"/>
<AppBarButton Icon="Cancel" Label="Cancel" Command="{Binding CommandResetIncludedRules}" Click="SetSpecialRuleFlyoutButton_Click"/>
</CommandBar>
</RelativePanel>
<Flyout.FlyoutPresenterStyle>
<Style TargetType="FlyoutPresenter">
<Setter Property="MinWidth" Value="100"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
</Flyout.FlyoutPresenterStyle>
</Flyout>
</Button.Flyout>
ListView Implementation;
public class ListViewWithSelectedItems : ListView
{
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
base.PrepareContainerForItemOverride(element, item);
ListViewItem listItem = element as ListViewItem;
Binding binding = new Binding();
binding.Mode = BindingMode.TwoWay;
binding.Source = item;
binding.Path = new PropertyPath("IsCheckedInList");
listItem.SetBinding(ListViewItem.IsSelectedProperty, binding);
}
}
I would like to create an items control that alternates the background color of an item based on the alternation index of the group it belongs to. In reference to the classes I list below, I would like it to, for example, have the background of the first three RandomHouse books as black, and then when it encounters the next Publisher, the background changes back to white, and so on and so forth for as many unique publishers there are. The number and name of the publishers is nondeterministic and is only evaluated at runtime. I have tried to do it with xaml to the best of my ability but it doesnt seem the alternationindex can be accessed for a GroupItem for whatever reason. Any help would be appreciated.
class Book
{
String Publisher {get; set;}
String Title {get; set;}
}
class ViewModel
{
var listBooks = new ObservableCollection<Book>();
listBooks.Add(new Book(){Publisher = "RandomHouse", Title = "Title1"});
listBooks.Add(new Book(){Publisher = "RandomHouse", Title = "Title2"});
listBooks.Add(new Book(){Publisher = "Penguin", Title = "Title5"});
ObservableCollection<Book> ListBookItems {get {return listBooks.Orderby(e => e.Publisher).ToList(); } }
}
<UserControl.Resources>
<Style TargetType="ItemsControl" x:Key="ListBookStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ScrollViewer CanContentScroll="True">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="FontFamily">
<Setter.Value>Consolas</Setter.Value>
</Setter>
</Style>
<DataTemplate DataType="{x:Type models:Book}">
<Grid IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Publisher" Width="100"/>
<ColumnDefinition SharedSizeGroup="Title" Width="100"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock
HorizontalAlignment="Left"
Text="{Binding Publisher}"
Grid.Column="0"
FontWeight="Bold"
Margin="5"/>
<TextBlock
HorizontalAlignment="Left"
Text="{Binding Title}"
Grid.Column="1"
FontWeight="Bold"
Margin="5"
/>
</Grid>
</DataTemplate>
<CollectionViewSource x:Key="ListBookItems" Source="{Binding ListBookItems}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Publisher"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</UserControl.Resources>
<DockPanel>
<ItemsControl
ItemsSource="{Binding Source={StaticResource ListBookItems}}"
Style="{StaticResource ListBookStyle}">
<ItemsControl.GroupStyle>
<GroupStyle AlternationCount="2">
<GroupStyle.ContainerStyle >
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Foreground" Value="#FF444444"/>
<Setter Property="Background" Value="#FF000000"/>
<!--<Style.Triggers>
<Trigger Property="AlternationIndex" Value="0">
<Setter Property="Foreground" Value="#FF444444"/>
<Setter Property="Background" Value="#FFD9D9D9"/>
</Trigger>
<Trigger Property="AlternationIndex" Value="1">
<Setter Property="Foreground" Value="#FF444444"/>
<Setter Property="Background" Value="#FFEFEFEF"/>
</Trigger>
</Style.Triggers>-->
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ItemsControl.GroupStyle>
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer CanContentScroll="True">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DockPanel>
You are very close. You just need to specify ItemsControl.AlternationIndex as the property name in each trigger, instead of just AlternationIndex.
That said, frankly I had second-thoughts about even proposing this as an answer, except that I can't actually get that to work. That is, while I can see in the debugger that it correctly sets the GroupItem.Background property value as desired, I see no visible effect on-screen. It's as if the items-presenter for the group is ignoring the GroupItem's background property.
The reason I'm going ahead and posting this as an answer even though it doesn't completely address the issue is that getting the GroupItem.Background property value to be respected by the actual presenter in the GroupItem is a completely different problem than correctly using the AlternationIndex value. So while you can use this answer to get the AlternationIndex value to be correctly bound, you will need to do some more work and/or post another question to dig into why having correctly set the Background property value, that does not actually change the background as shown on the screen.
I wish I could also explain how to get the background property in GroupItem to affect the display on the screen. I hope that if you figure that out, you will at least follow up with a comment here, explaining the answer. :) (Or if you post a question and someone else explains it, comment with a reference to that answer).
I've got a weird problem where a GridView I have bound to a CollectionViewSource shows the wrong data for the last items. But the actual binding is correct. If I listen for ItemClicked, the DataContext is correct, the UI is just displaying the info for a previous item in the GridView. My goal is to bind to a grouped set of data in a CollectionViewSource, but I've even had it happen if I'm just binding directly to an ObservableCollection.
Here's my XAML:
<Page.Resources>
<CollectionViewSource x:Name="CuratedCVS" IsSourceGrouped="True" />
</Page.Resources>
<SemanticZoom Padding="0">
<SemanticZoom.ZoomedInView>
<GridView x:Name="CuratedFeedsList"
ItemsSource="{Binding Source={StaticResource CuratedCVS}}"
ItemTemplate="{StaticResource CuratedFeedItemTemplate}"
SelectedItem="{Binding SelectedFeed, Mode=TwoWay}"
SelectionMode="Single"
IsSwipeEnabled="True"
IsSynchronizedWithCurrentItem="False"
ShowsScrollingPlaceholders="True"
Padding="20,0">
<GridView.GroupStyle>
<GroupStyle HeaderTemplate="{StaticResource CuratedFeedHeaderTemplate}"/>
</GridView.GroupStyle>
</GridView>
</SemanticZoom.ZoomedInView>
<SemanticZoom.ZoomedOutView>
<ListView Background="{Binding SecondaryBackgroundBrush, Source={StaticResource ThemeManager}}"
ItemsSource="{Binding Source={StaticResource CuratedCVS}, Path=CollectionGroups}"
ItemTemplate="{StaticResource CuratedFeedJumpTemplate}"
Padding="0,10">
</ListView>
</SemanticZoom.ZoomedOutView>
</SemanticZoom>
And here's my code to group my data (which seems to work):
var result =
from f in CuratedFeeds
group f by f.Category into g
orderby g.Key
select g;
CuratedCVS.Source = result;
(Where CuratedFeeds is an ObservableCollection)
Has anyone seen this before? This only happens in a Windows 8.1 app. It works flawlessly in a Windows Phone 8.1 app.
So I discovered what the problem was, and unfortunately it didn't have anything to do with the code I posted. I was customizing the ItemContainerStyle, where I used this:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ListViewItemPresenter Content="{Binding}" Margin="0"
SelectedBackground="{Binding SecondaryBackgroundBrush, Source={StaticResource ThemeManager}}"
SelectedForeground="{Binding ForegroundBrush, Source={StaticResource ThemeManager}}"
PlaceholderBackground="{Binding BackgroundBrush, Source={StaticResource ThemeManager}}"
PointerOverBackground="{Binding SecondaryBackgroundBrush, Source={StaticResource ThemeManager}}"
SelectionCheckMarkVisualEnabled="False"
Padding="0,0,0,0"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
In this code, the problem was the Content="{Binding}". I don't know why, but this was screwing up the data. All I had to do was remove the Content="{Binding}" and it worked perfectly.
I want to take the highlight background off of the radtreeview. I created a style to do this, but I keep getting errors and exceptions such as "Items collection must be empty." If I comment out the style the application works fine, so I know that it is the cause of the problem. I am fairly new to WPF, and I am sure I just don't understand how to use styles yet.
Thanks for your help. Here is the code.
<Grid x:Name="LayoutRoot" Background="Salmon">
<telerik:RadTreeView x:Name="radTreeView" Margin="8" ItemsSource="{Binding Errors}" Background="Salmon" Style="{StaticResource treeStyle}">
<Style TargetType="{x:Type telerik:RadTreeViewItem}" x:Name="treeStyle">
<Setter Property="Focusable" Value="False"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="{x:Null}"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
</Trigger>
</Style.Triggers>
</Style>
<telerik:RadTreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding SubItems}" >
<Grid Background="Salmon">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding Description}" IsHitTestVisible="False" />
<ListBox Grid.Row="1" ItemsSource="{Binding Messages}" Margin="20,0,0,0" BorderBrush="#00000000" BorderThickness="0" Background="Salmon" IsHitTestVisible="False" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Message}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</HierarchicalDataTemplate>
</telerik:RadTreeView.ItemTemplate>
</telerik:RadTreeView>
</Grid>
</UserControl>
If you know that this is not going to work, I was also trying to get rid of the highlight with the style code:
<Style TargetType="TreeViewItem">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#FFF"/>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="#000"/>
</Style.Resources>
</Style>
You get exceptions because your style tag is actually an item in the tree, and you have ItemsSource set.
Surround the style with <telerik:RadTreeView.ItemContainerStyle> tag.
This should solve the exception but it will not give you the result that you expect since the control template of the tree view item is actually showing another border that is not affected by the Background property. You will need to change the control template.
Telerik change the styles between releases, so giving you a template of a wrong version will probably won't help you.
But, you can go to the installation folder for Telerik and look for a folder called "Themes". There you'll find a solution with all the themes for telerik.
Choose the one that you use.
Find the resource dictionary for the tree view and copy the style and template for the item to your project.
Change xmlns definitions, make sure you have all the brushes and resources that the style depends upon.
Run to see that the style is ok.
In the template, find the VisualState with x:Name="MouseOver" and delete the storyboard inside it.