Datatemplates while using theme does not work - WPF - c#

I am using the theme DarkExpression from WPF Futures.
It does not seem to work well with datatemplates.
Scenario 1:
Here is how it looks like without datatemplates:
Code:
<ListView Name="playlistListView" ItemsSource="{Binding PlaylistList}" Margin="0" SelectionChanged="DatabindedPlaylistListView_SelectionChanged" Background="{x:Null}" Opacity="0.98">
<ListView.View>
<GridView>
<GridViewColumn Width="Auto" DisplayMemberBinding="{Binding Name}">
<GridViewColumnHeader HorizontalContentAlignment="Left" Content="Playlist" Tag="Playlist"/>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Scenario 2:
Here is how it looks like trying to use datatemplates while using the theme:
Code:
<ListView Name="playlistListView" ItemsSource="{Binding PlaylistList}" Margin="0" SelectionChanged="DatabindedPlaylistListView_SelectionChanged" Background="{x:Null}" Opacity="0.98">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<UserControls:SongDataTemplate Margin="4" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Scenario 3:
Here is how it looks like trying to use datatemplates while overriding the theme:
Code:
<UserControl.Resources>
<Style x:Key="ListViewItemStretch" TargetType="{x:Type ListViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Background" Value="Transparent" />
</Style>
</UserControl.Resources>
<Grid x:Name="LayoutRoot">
<ListView Name="playlistListView" ItemContainerStyle="{StaticResource ListViewItemStretch}" ItemsSource="{Binding PlaylistList}" Margin="0" SelectionChanged="DatabindedPlaylistListView_SelectionChanged" Background="{x:Null}" Opacity="0.98">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<UserControls:SongDataTemplate Margin="4" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I want to keep the theme style but I also want to use datatemplates to define how a playlist should look like. Any suggestions?
Note: In scenario 2 and 3 I had to remove
<ListView.View>
<GridView>
<GridViewColumn Width="Auto" DisplayMemberBinding="{Binding Name}">
<GridViewColumnHeader HorizontalContentAlignment="Left" Content="Playlist" Tag="Playlist"/>
</GridViewColumn>
</GridView>
</ListView.View>
Before the datatemplate would be used.
Edit:
The solution given below, works if the type is changed to ListBox and I am using a TextBox instead. I can't however make it work with a ListView.

You are doing it wrong.
When you want to customize ListView you need to work with the View property which is of type ViewBase. Derive a custom View from ViewBase, assign it to ListView.View and you're done.
There's an example in ViewBase Class Documentation

Try by using BasedOn
<Style BasedOn={StaticResource {x:Type ListViewItem}} x:Key="ListViewItemStretch" TargetType="{x:Type ListViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Background" Value="Transparent" />
</Style>

does it work if you substitute
<Grid>
<UserControls:SongDataTemplate Margin="4" />
</Grid>
with a TextBox, for example?
The problem could be generated by your user control..

Related

C# XAML Master Detail Binding does not work

I want to display a List in a ListView with Master Detail View. The Master View works fine, but the binding to the detail view is not working. What am i doing wrong?
Code Behind:
DataContext = new VirtualizingCollection<LinesSummary>(fs, 100)
LinesSummary Class:
public class LinesSummary {
public string dateString { get; set; }
}
XAML:
<StackPanel>
<ListView Margin="5" Style="{DynamicResource lvStyle}" Height="200" x:Name="Master"/>
<ListView Margin="5" Style="{DynamicResource lvStyle_Detail}" Height="200" x:Name="Detail"/>
</StackPanel>
Dynamic Resource for Master View:
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
<Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling"/>
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="True"/>
<Setter Property="ListView.ItemsSource" Value="{Binding}"/>
<Setter Property="ListView.View">
<Setter.Value>
<GridView>
<GridViewColumn Header="Date" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding dateString}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</Setter.Value>
</Setter>
</Style>
Dynamic Resource for Detail View:
<Style x:Key="lvStyle_Detail" TargetType="{x:Type ListView}">
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
<Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling"/>
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="True"/>
<Setter Property="ListView.ItemsSource" Value="{Binding ElementName=Master, Path=SelectedItem.LinesSummary}"/>
<Setter Property="ListView.View">
<Setter.Value>
<GridView>
<GridViewColumn Header="aaa" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding dateString}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</Setter.Value>
</Setter>
</Style>
The ItemsSource of a ListView can only be bound to an IEnumerable so even if you bind the ItemsSource property of the second ListView like this it won't work:
ItemsSource="{Binding ElementName=Master, Path=SelectedItem}"
...because LinesSummary is not an IEnumerable.
Since there is only a maximum of one item selected in Master, you might as well bind a TextBlock to the dateString property of its SelectedItem:
<StackPanel>
<ListView Margin="5" Style="{DynamicResource lvStyle}" Height="200" x:Name="Master"/>
<ListView Margin="5" Style="{DynamicResource lvStyle_Detail}" Height="200" x:Name="Detail">
<ListViewItem>
<TextBlock Text="{Binding Path=SelectedItem.dateString, ElementName=Master}" />
</ListViewItem>
</ListView>
</StackPanel>
Remove this setter from the lvStyle_Detail:
<Setter Property="ListView.ItemsSource" Value="{Binding ElementName=Master, Path=SelectedItem.LinesSummary}"/>

Dividing listview into columns, with horizontal scroll (wpf)

I have a list view that is divided into two columns. The problem is what happens if the information that comes into the list view is too long of a string.
If I make a fixed width, it will cut some of it. If I make an automatic width, then the initial state of the listview columns will look bad.
Fixed Width:
Automatic Width:
Any ideas what can I do to solve this?
relevant XAML:
<ListView Width="Auto" Height="Auto" Margin="10" Background="#092E3E" Foreground="White" ItemsSource="{Binding BackupEvents}" >
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
...
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView AllowsColumnReorder="False">
<GridView.ColumnHeaderContainerStyle>
...
</GridView.ColumnHeaderContainerStyle>
<GridView.Columns>
<GridViewColumn Width="200" Header="Time" DisplayMemberBinding="{Binding LVTime}"/>
// auto or fixed?
<GridViewColumn Width="Auto"/"520" Header="Details" DisplayMemberBinding="{Binding LVDetails}"/>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
The best solution I think would be if I could make the column size fixed, but the text/list-entries to wrap into multiple lines if needed. But I'm not sure how to do that...
You can show ellipsis after certain width of data
The best solution I think would be if I could make the column size fixed, but the text/list-entries to wrap into multiple lines if needed. But I'm not sure how to do that...
You could define an implicit TextBlock Style that sets the TextWrapping property of all TextBlocks in the GridView to Wrap:
<ListView Width="Auto" Height="Auto" Margin="10" Background="#092E3E" Foreground="White" ItemsSource="{Binding BackupEvents}" >
<!-- HERE: -->
<ListView.Resources>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="TextBlock.TextWrapping" Value="Wrap" />
</Style>
</ListView.Resources>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
...
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView AllowsColumnReorder="False">
<GridView.ColumnHeaderContainerStyle>
...
</GridView.ColumnHeaderContainerStyle>
<GridView.Columns>
<GridViewColumn Width="200" Header="Time" DisplayMemberBinding="{Binding LVTime}"/>
// auto or fixed?
<GridViewColumn Width="Auto"/"520" Header="Details" DisplayMemberBinding="{Binding LVDetails}"/>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>

Is an XAML file portable to Xamarin Macintosh?

I don't have access to a Macintosh to test this on (i.e, I can't load the Xamarin Mac components) so I don't have a way to test this. But...below is the XAML of a WPF app. Most everything in the app appears to be Xamarin-compliant -- WebClient calls, populating my form fields through an XMLDocument and binding, for instance -- but I don't know of the XAML is compliant. So, here it is:
<Window x:Class="IMManager.ImManagerWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="IMM Media Manager"
SnapsToDevicePixels="True"
WindowState="Normal"
MaxWidth="720"
ResizeMode="NoResize"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<Style x:Key="AlternatingListViewItemStyle" TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<!-- setting up triggers for alternate background colors -->
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="LightGray"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="2">
<Setter Property="Background" Value="White"></Setter>
</Trigger>
</Style.Triggers>
<!-- setting row height here -->
<Setter Property="Height" Value="25" />
</Style>
</Window.Resources>
<ListView x:Name="LvAlbums" ItemsSource="{Binding XPath=/downloads/Album}" Width="680">
<ListView.ItemTemplate>
<DataTemplate x:Name="dt1">
<StackPanel x:Name="spAlbum" HorizontalAlignment="Left">
<TextBlock
Text="{Binding XPath=#Artist,StringFormat='Artist: {0}'}"
FontSize="16px"
/>
<TextBlock
Text="{Binding XPath=#Name,StringFormat='Album: {0}'}"
FontSize="16px"
/>
<ListView x:Name="lvTracks" ItemsSource="{Binding XPath=Item}" ItemContainerStyle="{StaticResource AlternatingListViewItemStyle}" AlternationCount="2">
<ListView.View>
<GridView>
<GridViewColumn Header="Track" Width="460">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock x:Name="trackName" Text="{Binding XPath=#Name}" Width="450" LineHeight="25" Height="25" VerticalAlignment="Center" Margin="0,3,0,0">
</TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Progress" Width="175">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Canvas VerticalAlignment="Center" Height="25">
<ProgressBar Foreground="GreenYellow" Name="PbStatus" Value="{Binding XPath=#Progress, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Minimum="0" Maximum="100" Height="20" VerticalAlignment="Center" Margin="0,3,0,0" Width="165"/>
<TextBlock FontFamily="Segoe UI" LineHeight="25" FontWeight="Bold" Text="{Binding XPath=#Info, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Height="20" Width="165" VerticalAlignment="Center" Margin="0,4,0,0"/>
</Canvas>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Can Mac Xamarin handle this or something close to this?
No. Xamarin Mac does not use XAML. Xamarin Forms does, but it is a different syntax than the XAML used in WPF.

c# WPF ListView Displays either Grouping of Data, but not both

I have a bound ListView on a Window and I've setup XAML to do grouping, but when I try to apply it I either get only data or grouping with no data. The XAML is as follows:
<ListView x:Name="lvNav" HorizontalAlignment="Left" Height="100" Margin="331,41,0,0" VerticalAlignment="Top" Width="166">
<ListView.View>
<GridView>
<GridViewColumn Header="Customer" DisplayMemberBinding="{Binding serviceID}" />
<GridViewColumn Header="S/N" DisplayMemberBinding="{Binding machineID}" />
</GridView>
</ListView.View>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" FontWeight="Bold" />
</StackPanel>
</Expander.Header>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
The code that loads the data is:
System.Data.Entity.DbSet<srsr> srsrs = _fa.srsrs;
srsrs.Load();
lvNav.ItemsSource = srsrs.Local;
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lvNav.ItemsSource);
PropertyGroupDescription pgd = new PropertyGroupDescription("stateID");
view.GroupDescriptions.Add(pgd);
I'm assuming I'm missing something relatively simple here, so hopefully someone can point me in the right direction.
If you would use the MVVM approach i.e. without code behind, you could use this:
<CollectionViewSource Source="{Binding PropertyOnYourVM}" x:Key="NameOfTheGrouping">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="PropertyToGroupOn"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
you can then use it like this on your ListView:
<ListView ItemsSource="{Binding Source={StaticResource NameOfTheGrouping}}">
<ListView.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource YourStyleNameHere}"/>
</ListView.GroupStyle>
But because you are NOT using MVVM you will have to do it in code behind.
BTW: you forgot <ItemsPresenter /> in your xaml, which goes between </Expander.Header> and </Expander>

WPF - Listview Item Margin

My Listview items are not stretching to the full width of the column. There is always a margin on the right of my cell border. I would like to get the bordered area to stretch over the full column width and get rid of any padding, margins or anything else on the left and right of my content. The goal is to have the borders fill the whole space in each cell.
I have already applied stretching and set the margins to "-6,0,-6,0" but that doesn't seem to solve the problem.
Here is my code:
<Grid>
<Grid.Resources>
<x:Array Type="{x:Type sys:String}" x:Key="items">
<sys:String>Foo</sys:String>
<sys:String>Bar</sys:String>
<sys:String>Spong</sys:String>
</x:Array>
</Grid.Resources>
<ListView ItemsSource="{StaticResource items}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Margin"
Value="-6, 0,-6,0" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Data" Width="80">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Border BorderThickness="2" BorderBrush="Black" HorizontalAlignment="Stretch">
<TextBox Text="{Binding .}" />
</Border>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Length"
DisplayMemberBinding="{Binding Length}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
I got it working using a DataTemplate resource and setting the border's margin to -6.
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.Resources>
<x:Array Type="{x:Type sys:String}" x:Key="items">
<sys:String>Foo</sys:String>
<sys:String>Bar</sys:String>
<sys:String>Spong</sys:String>
</x:Array>
<DataTemplate x:Key="MyDataTemplate">
<Border BorderThickness="2" BorderBrush="Black" Margin="-6">
<TextBox Text="{Binding .}" Margin="0" Padding="0"/>
</Border>
</DataTemplate>
</Grid.Resources>
<ListView ItemsSource="{StaticResource items}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView >
<GridViewColumn Header="Data" Width="80" CellTemplate="{StaticResource MyDataTemplate}" />
<GridViewColumn Header="Length" DisplayMemberBinding="{Binding Length}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
Just set the Margin for your Border element:
<Border Margin="-6,0,-6,0" BorderThickness="2" BorderBrush="Black" HorizontalAlignment="Stretch">
<TextBox Text="{Binding .}" />
</Border>
Alternative solution
typeof(GridViewRowPresenter).GetField("_defalutCellMargin", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.GetField).SetValue(null, new Thickness(0));
I do it with
HorizontalContentAlignment="Stretch"
on ListView

Categories