ItemsControl fill remainder of columns - wpf

We have a page which we use to display a lot of information at once.
On this page we want a readouts section in the top left, and then for the remainder of that columns, and for the rest of the page we want to display some sensor outputs. Layout is roughly the following.
What I have attemtped so far is as follows
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<controls:ParameterDisplayPanel HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Columns="1"
Grid.Column="0"/>
<ItemsControl
Grid.Column="0"
Grid.ColumnSpan="3"
ItemsSource="{Binding ItemCollection, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<views:SensorControlView
DataContext="{Binding}"
Width="280"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
This returns a layout where the sensors overlap the readout panel.
If instead of using a grid I use a wrap panel, I get a row at the top which displays the readouts, and then all the sensor states start beneath that first row.

You could try sth. like this.
Note that this is not done yet. It's just a raw example.
Basically what I did is I added the SensorReadoutControl first and then added the remaining SensorItems to the same collection.
I then used a WrapPanel.
This is what it looks like (added some BackgroundColors to make more clear what control is where !)
So here is my example code:
XAML:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate x:Key="SensorItemTemplate">
<Grid Background="Gray" Height="50">
<Border BorderThickness="1" BorderBrush="Pink"
Margin="5">
<TextBlock Text="{Binding Name}"
Width="200"
TextAlignment="Center"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</Border>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid>
<ItemsControl ItemsSource="{Binding Items}"
Background="Green"
ItemTemplate="{StaticResource SensorItemTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical"></WrapPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
ViewModel:
public class ViewModel
{
public ViewModel()
{
Grid grid = new Grid() { Width = 200, Height = 150, Background = Brushes.Blue };
grid.Children.Add(new TextBlock()
{
Text = "Sensor readouts" ,
VerticalAlignment = System.Windows.VerticalAlignment.Center,
HorizontalAlignment = System.Windows.HorizontalAlignment.Center
});
Items.Add(grid);
for (int i = 0; i < 50; i ++)
{
Items.Add(new SensorItem() { Name = $"SensorItem {i}" });
}
}
public List<object> Items { get; set; } = new List<object>();
}
public class SensorItem
{
public string ItemTypeName { get; set; } = "SensorItem";
public string Name { get; set; }
}
I guess that won't satisfy your needs but it may help you to progress.

Related

WPF: Fast auto-sizing by height grid

I have to implement window containing several tables into one scroll viewer. This means that this tables should be stretched by the content. User able to add / remove items (rows) to these tables.
The concept was shown on the following mockup. The main problem is that grid should not have scroll bar, it should have dynamic height.
For the moment this interface is implemented as ItemsControl inside the ScrollViewer. In the ItemTemplate of the ItemsControl added DataGrid to represent tabular data.
<ScrollViewer CanContentScroll="True"
HorizontalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Path=Groups}"
VirtualizingStackPanel.IsVirtualizing="True">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="125" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0"
Style="{StaticResource ResourceKey=LabelBaseStyle}"
Content="{Binding Path=GroupLabel}"
HorizontalAlignment="Right"/>
<Button Content="{x:Static Member=Resources:CommonStrings.Delete}"
Style="{StaticResource ResourceKey=ButtonBaseStyle}"
VerticalAlignment="Center" />
<DataGrid Grid.Row="0" Grid.Column="1"
AutoGenerateColumns="False"
ItemsSource="{Binding Path=Items}">
<DataGrid.Columns>
<!-- 21 text columns here -->
</DataGrid.Columns>
</DataGrid>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
This solution works fine until some amount of data has been added. Now on the 7 tables (grids) with about 50 items in the each the application is impossible slow: it takes several minutes to render it. After profiling I've found that almost all the time is spent on Measure and Arrange methods. Also I've found recomentation to not to use DataGrid into contrainers which measures it with infinity. So I undestand the problem, but I cannot change interface.
I've tried to write the same interface without DataGrid: replaced it by ItemsControl with TextBlocks. This solution works fine. But I've several similar interfaces and it's not looks very good to write so much similar code. The code shown below is replacement for DataGrid in previous sample:
<ItemsControl ItemsSource="{Binding Path=Items}"
VirtualizingStackPanel.IsVirtualizing="True"
Grid.Row="0" Grid.Column="1">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Type}" />
<!-- Another 20 TextBlocks here -->
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
So I need to implement own UserControl or find one ready to use.
Can anyone suggest me something? Maybe some workaround or lightweight control?
Re-did my answer....this is a better solution for your issue. I'm sure you can figure out how to modify this to work:
In my Main Window Xaml:
<ScrollViewer Height="Auto" Width="Auto" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Visible">
<StackPanel Height="Auto" Width="Auto">
<ItemsControl ItemsSource="{Binding ItemList}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type wpfmvvmtest:itemTypeA}">
<wpfmvvmtest:testUC></wpfmvvmtest:testUC>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
</StackPanel>
</ScrollViewer>
Here's the Main ViewModel for the Main Window (testVM) all done in constructor for example:
public testVM()
{
ItemList = new ObservableCollection<object>();
Random rnd = new Random();
for (int i = 0; i < 3; i++)
{
itemTypeA item = new itemTypeA(rnd.Next(100));
ItemList.Add(item);
}
}
public ObservableCollection<object> ItemList { set; get; }
and here's what "itemTypeA" is like:
public itemTypeA(int count)
{
Items = new DataTable();
Items.Columns.Add("One");
Items.Columns.Add("Two");
Items.Columns.Add("Three");
Items.Columns.Add("Four");
Description = "Count = " + count;
for (int i = 0; i < count; i++)
{
DataRow dr = Items.NewRow();
dr[0] = i*1;
dr[1] = i * 2;
dr[2] = i * 3;
dr[3] = i * 4;
Items.Rows.Add(dr);
}
}
public DataTable Items { set; get; }
Here's the important part(Make sure you have no height/width properties set in your UserControl for the DataTemplate (That allows for the DataGrid to set the height/width):
<UserControl x:Class="wpfmvvmtest.testUC"
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"
d:DataContext="d:designInstance itemTypeA"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" HorizontalAlignment="Stretch" Content="{Binding Description}"></Label>
<Border Grid.Row="1" BorderBrush="Black" BorderThickness="2">
<DataGrid ItemsSource="{Binding Path=Items}">
</DataGrid>
</Border>
</Grid>
</UserControl>

How to crop the elements not fit to a WrapPanel

The example of the WrapPanel.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ItemsControl Grid.Row="1" Style="{StaticResource DestinationItemsControlStyle}"
DataContext="{StaticResource ViewModelKey}"
ItemsSource="{Binding Stations}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Margin="5" Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Style="{DynamicResource DestinationButtonStyle}">
<TextBlock Text="{Binding FullName}" Style="{StaticResource DestinationTextBlockStyle}"
TextTrimming="CharacterEllipsis" />
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
If there are to many elements then all these "excessive" elements become rendered in half of their's real size. Is there a way not to render such the elements?
Am I forced to use something like VirtualizedWrapPanel?
I also want to notice that I can't use a scroll bar. All the "excessive" elements should be rendered on the next page which can be visited by the user's click on the button "Next".
This XAML:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="1024" Width="1280">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ItemsControl Name="ItemsControl1" Grid.Row="1"
ItemsSource="{Binding Stations}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Margin="5" Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Margin="20" MinHeight="50" MinWidth="400">
<TextBlock Text="{Binding FullName}"
TextTrimming="CharacterEllipsis" />
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
and the addition of 70 items in the Stations collection at startup, produces this result:
What does your DestinationItemsControlStyle look like?
For reference, this is the code-behind that runs on Startup:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ViewModelKey vmk = new ViewModelKey();
ItemsControl1.DataContext = vmk;
}
}
and in the ViewModelKey class:
public class ViewModelKey : INotifyPropertyChanged
{
public ObservableCollection<station> Stations { get; set; }
public ViewModelKey()
{
Stations = new ObservableCollection<station>();
for (int i = 1; i < 70; i++)
{
Stations.Add(new station("This is station " + i.ToString()));
}
}
private void NotifyPropertyChanged(string info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}

How can I get SelectedItem and show Headers using ItemsControl?

I am working on WPF Windows Application. I'm using ItemsControl to show collection list. Working on this I found there is no SelectedItem property in ItemsControl. Then how can I get the Selected Item from the ItemsControl. And also How can I display the Headers of ItemsControl.
<ItemsControl ItemsSource="{Binding CustomSalesProducts, Mode=TwoWay}">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<Border>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsPresenter/>
</ScrollViewer>
</Border>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel CanHorizontallyScroll="True" CanVerticallyScroll="True" Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid x:Name="SalesGrid" Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<controls:HeaderedContentControl Header="{Binding ProductName, Mode=TwoWay}" Margin="{DynamicResource Margin4}" Style="{DynamicResource HeaderedContentControlStyle}" HorizontalContentAlignment="Right">
</controls:HeaderedContentControl>
<TextBox Text="{Binding OrderQty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Margin="{StaticResource Margin4}" Style="{DynamicResource MiniTextBoxStyle}" ToolTip="Quantity" />
<TextBlock Text="{Binding UnitSalePrice, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="1" Margin="{StaticResource Margin4}" ToolTip="Price"/>
<TextBox Text="{Binding Discount, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Column="2" Grid.Row="1" Margin="{StaticResource Margin4}" Style="{DynamicResource MiniTextBoxStyle}" ToolTip="Discount"/>
<TextBlock Text="{Binding TaxAmount, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Column="3" Grid.Row="1" Margin="{StaticResource Margin4}" ToolTip="Tax Amount"/>
<TextBlock Text="{Binding LineTotal, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Column="4" Grid.Row="1" Margin="{StaticResource Margin4}" ToolTip="Total"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Thanks,
As you said there is no SelectedItem in the ItemsControl. You can use ListBox instead.
A bit late to the party, but I came across the same problem, and in the hopes that this can help someone else here's how I rolled my own SelectedItem since I didn't want to use a ListBox.
You could expose a SelectedCustomSalesProduct property to the class you are using as your DataContext, and then you can keep track of the selected item yourself by setting it when the item is selected.
In your SalesGrid, you could add event handlers for the MouseLeftButtonDown and for the TouchDown events, and use the Tag property to keep a reference to the item being rendered as such:
Please note that in my case, I was using a StackPanel instead of a Grid, and I didn't compile the code below, use it for illustrative purposes.
By using this example you should be able to get the general idea and set the Selected item in your business service.
<DataTemplate>
<Grid x:Name="SalesGrid" Background="White"
Tag="{Binding}"
TouchDown="DataTemplate_Touch"
MouseLeftButtonDown="DataTemplate_Click">
Then in your UserControl/window's code behind you can keep track of the selected item as such:
/// <summary>
/// MyScreen.xaml
/// </summary>
public partial class MyScreen : UserControl
{
private MyServiceWrapper _serviceWrapper;
public MyScreen()
{
InitializeComponent();
}
public MyScreen(MyServiceWrapper serviceWrapper)
{
//Instrumentation.Log(typeof(MyScreen), LogTypes.Trace, "Creating instance of MyScreen");
this._serviceWrapper = serviceWrapper;
// Set your DataContext, is this the class that would also have your
// CustomSalesProducts property exposed
this.DataContext = this._serviceWrapper;
InitializeComponent();
}
private void DataTemplate_Touch(object sender, System.Windows.Input.TouchEventArgs e)
{
SetSelectedCustomSalesProduct(sender);
}
private void DataTemplate_Click(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
SetSelectedCustomSalesProduct(sender);
}
private void SetSelectedCustomSalesProduct(object sender)
{
_serviceWrapper.SelectedCustomSalesProduct = ((Grid)sender).Tag as CustomSalesProduct;
}
}
I found that for using headers there is HeaderdItemsControl. With this I can add headers and also it is not repeatable. But problem with this is that we have to define static size for header and its item if we define auto size then the UI of headeredItemsControl is not perfect so we have to give its static size.
You can read this for how to use HeaderedItemsControl?

Silverlight Listbox scrolling only works if i set the height

i have a listbox and i am trying to make the scrolling work without having to set the height, is this possible? Thanks. Below is the code. The scrolling does not work.
<ListBox Name="EmployeeListBox" Background="Transparent"
SelectionMode="Single"
ItemsSource="{Binding Employees, Mode=TwoWay}" >
<ListBox.ItemTemplate>
<DataTemplate >
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition Width="140" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" FontWeight="Bold" Text="Name:" />
<TextBlock x:Name="TextBlock1" Grid.Column="1" Grid.Row="0"
Text="{Binding Name}" />
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
and viewmodel:
public class EmployeeDataContext
{
public List<Employee> Employees { get; set; }
public EmployeeDataContext()
{
GetEmployeeList();
}
private void GetEmployeeList()
{
Employees = new List<Employee>();
for (int i = 0; i < 100; ++i)
{
Employees.Add(new Employee() { Name = "Gema Arterton" });
}
}
}
public class Employee
{
public string Name { get; set; }
}
(sorry for my bad english)
It depends too on what control is the listbox inside. If your listbox is inside a Grid, it should take all the space of that grid - if it is inside a stackpanel it will use the least amount os space possible so you will have to use fixed height/width. Try this:
<UserControl...>
<Grid>
<ListBox HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
</ListBox>
</Grid>
</UserControl/>
The listbox should use all screen size and show vertical scrollbars if there is enough items.
You can set the height in scrollviewer
<ScrollViewer VerticalScrollBarVisibility="Visible" Height="480">
<Grid Margin="0,0,0,50">
</Grid>
</ScrollViewer>

Stretching the items in a WPF ListView within a ViewBox

I have a frustrating problem that I would much appreciate some help with. I have a ListView within a ViewBox and I can't get the items within the ListView to stretch horizontally.
Here is the XAML:
<Window x:Class="WpfApplication3.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication3"
Title="Window1">
<Window.Resources>
<local:Inning x:Key="inning">
<local:Inning.Skins>
<local:Skin SkinNumber="1"></local:Skin>
<local:Skin SkinNumber="2"></local:Skin>
<local:Skin SkinNumber="3"></local:Skin>
</local:Inning.Skins>
</local:Inning>
</Window.Resources>
<Grid DataContext="{StaticResource inning}">
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Background="Black"
Text="SKINS"
Foreground="White"
FontSize="80"
FontWeight="Bold"
HorizontalAlignment="Center"></TextBlock>
<Grid Margin="2"
Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Viewbox>
<ListView Name="lvSkinNumbers"
ItemsSource="{Binding Skins}"
HorizontalAlignment="Stretch"
Background="Black"
VerticalAlignment="Stretch"
VerticalContentAlignment="Stretch">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock FontSize="250"
VerticalAlignment="Stretch"
LineStackingStrategy="BlockLineHeight"
Margin="2"
TextAlignment="Center"
HorizontalAlignment="Stretch"
Background="Black"
Foreground="White"
Text="{Binding SkinNumber}"></TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Viewbox>
<Viewbox Grid.Column="1">
<ListView Name="lvFirstInningSkins"
ItemsSource="{Binding Skins}"
Grid.Column="1"
HorizontalContentAlignment="Stretch"
Background="Black">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock FontSize="250"
VerticalAlignment="Stretch"
LineStackingStrategy="BlockLineHeight"
Margin="2"
TextAlignment="Center"
HorizontalAlignment="Stretch"
Background="Green"
Foreground="White"
Text="{Binding SkinNumber}"></TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Viewbox>
<Viewbox Grid.Column="2"
HorizontalAlignment="Stretch">
<ListView Name="lvSecondInningSkins"
ItemsSource="{Binding Skins}"
Grid.Column="2"
HorizontalAlignment="Stretch"
Background="Black">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock FontSize="250"
VerticalAlignment="Stretch"
LineStackingStrategy="BlockLineHeight"
Margin="2"
TextAlignment="Center"
HorizontalAlignment="Stretch"
Background="Green"
Foreground="White"
Text="{Binding SkinNumber}"></TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Viewbox>
</Grid>
</Grid>
</Window>
Here is the code behind with the definitions of the Skin and Inning objects:
using System;
using System.Windows;
using System.ComponentModel;
using System.Collections.ObjectModel;
namespace WpfApplication3
{
public class Inning
{
private ObservableCollection<Skin> _skins = new ObservableCollection<Skin>();
public ObservableCollection<Skin> Skins
{
get { return _skins; }
set { _skins = value; }
}
}
public class Skin : INotifyPropertyChanged
{
public Skin()
{
}
public Skin( int skinNumber, Inning inning )
{
this.SkinNumber = skinNumber;
this.Inning = inning;
}
public Inning Inning { get; set; }
public int SkinNumber { get; set; }
public int SkinCount
{
get { return this.Inning.Skins.Count; }
}
public void Notify( string propertyName )
{
if ( PropertyChanged != null )
PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) );
}
public event PropertyChangedEventHandler PropertyChanged;
}
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
}
}
The number of skins that can occur in an inning can change, and can be changed by the user, so I've put the ListViews into ViewBoxes so they automatically resize accordingly when the number of skins change. The resulting window can be seen here: http://i52.tinypic.com/244wqpl.jpg
I've tried all sorts of combinations of HorzontalAlignment="Stretch" and HorizontalContentAlignment="Stretch" and tried modifying the ItemsPanel template but I can't for the life of me seem to figure out how to get the ListView to stretch horizontally. Is what I'm trying to do impossible without some code behind to alter the width of the ListView dynamically? Or am I missing something really simple?
Any help that anyone can offer would be most appreciated.
Thanks,
Matthew
Try setting the ItemContainerStyle for your ListView to something like:
<ListView>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
You also might need to set <Viewbox Stretch="Fill"/>.
After this, I think you can remove all those other "HorizontalAlignment = Stretch" and "HorizontalContentAlignment = Stretch" setters in your code since it probably won't be necessary anymore.
Unexpectedly setting ScrollViewer.HorizontalScrollBarVisibility="Disabled" also worked for me:
<ListView ItemsSource="{Binding SourceList}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">

Resources