How to display my List member in Listview WPF - wpf

i have working state.
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn
Width="120"
DisplayMemberBinding="{Binding Status}"
Header="Durumu" />
<GridViewColumn
Width="180"
DisplayMemberBinding="{Binding FromWho}"
Header="Kimden" />
<GridViewColumn
Width="200"
DisplayMemberBinding="{Binding Address}"
Header="Adres" />
<GridViewColumn
Width="50"
DisplayMemberBinding="{Binding Code}"
Header="Kodu" />
<GridViewColumn
Width="0"
DisplayMemberBinding="{Binding Order}"
Header="Sipariş" />
</GridView.Columns>
</GridView>
</ListView.View>
but this not enough for me.
I have wpf application. and I'm learning Binding
i can use with Default listview binding like above code (listview). but i making editing customize listview. and bind data
however, while i try display data just appear myList's System name.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="3*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DockPanel Grid.Row="1" VerticalAlignment="Center">
<ListView
x:Name="listVActiveOrder"
Width="560"
Height="222"
Margin="10,10,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
SelectionChanged="ListVActiveOrder_SelectionChanged"
ItemsSource="{Binding TakingOrderList}">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="GroupItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Address}" />
<TextBlock Grid.Column="1" Text="{Binding FromWho}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
</DockPanel>
<ListBox
x:Name="listProcessed"
Grid.Row="2"
Width="79"
Height="29"
Margin="721,16,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Visibility="Hidden" />
</Grid>
public LoginResponse loginResponse;
public RestClient client;
public listviewDeneme()
{
client = new RestClient(Constants.APIURL);
InitializeComponent();
}
private void ListVActiveOrder_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
listVActiveOrder.DataContext = new TakingOrderVM();
}
Where is my fault?

You can either set the DisplayMemberPath property of the ListView or ListBox to a name of the property of the TakingOrder class that you want to display:
<ListBox
x:Name="listProcessed"
DisplayMemberPath="FromWho"
...
Or you could define an ItemTemplate:
<ListView
x:Name="listVActiveOrder"
Width="560"
Height="222"
Margin="10,10,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
SelectionChanged="ListVActiveOrder_SelectionChanged"
ItemsSource="{Binding TakingOrderList}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Address}" />
<TextBlock Grid.Column="1" Text="{Binding FromWho}" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
There is no reason to use a ListView over a ListBox if you don't intend to use a GridView though.

Related

Color Change in WPF MVVM

I am completely new to wpf and MVVM. I have created a code which binds the values from the listView to the Textbox and Viceversa.
The data to the list view is sent from the database.
Now I would like to change the color of the row in the list view when text in the textbox is updated.
I also have similar connection of two checkboxes with the same listview. Could you please help since I could not find a correct solution for the same.
Below is my code:
<UserControl>
<Grid HorizontalAlignment="Center" Margin="20,20,20,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="236"></ColumnDefinition>
<ColumnDefinition Width="Auto" MinWidth="494"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="Mitarbeiter Status" Margin="0,0,0,10"/>
<TextBox Grid.Row="0" Grid.Column="1" Width="261" HorizontalAlignment="Left" HorizontalContentAlignment="Center" Text="{Binding ElementName=EmployeeStatusListView, Path=SelectedItem.Status, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged }"/>
<CheckBox Grid.Row="1" Grid.Column="0" Content="IsAdmin" Margin="0,10,0,10" IsChecked="{Binding ElementName =EmployeeStatusListView, Path=SelectedItem.IsAdmin,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnTargetUpdated=True }"/>
<CheckBox Grid.Row="1" Grid.Column="1" Content="IsMandatory" Margin="0,10,0,10" IsChecked="{Binding ElementName =EmployeeStatusListView, Path=SelectedItem.IsMandatory,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnTargetUpdated=True}"/>
<StackPanel Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Orientation="Horizontal" Margin="0,10,0,10" >
<Button Width="100" Content="Hinzufugen" Command="{Binding Path=AddCommand}" CommandParameter="{Binding ElementName=EmployeeStatusListView ,Path=SelectedItem}" Margin="100,10,30,0"/>
<Button Width="90" Content="Update" Command="{Binding Path=UpdateCommand}" CommandParameter="{Binding ElementName=EmployeeStatusListView, Path=SelectedItem}" Height="30" Margin="20,10,30,0" />
<Button Width="90" Content="Löschen" Command="{Binding Path=DeleteCommand}" CommandParameter="{Binding ElementName=EmployeeStatusListView, Path=SelectedItem}" Height="30" Margin="20,10,30,0" />
</StackPanel>
<ListView SelectedItem="EmployeeStatusSelect" SelectedIndex="0" Grid.Row="3" Grid.ColumnSpan="2" Name="EmployeeStatusListView" ItemsSource="{Binding EmployeeStatusList}" RenderTransformOrigin="0.502,0.66" Margin="0,20,0,-19" >
<ListView.View>
<GridView>
<GridViewColumn Header="ID" Width="120" DisplayMemberBinding="{Binding Id, Mode=TwoWay}"/>
<GridViewColumn Header="Mitarbeiter Admin Nummer " Width="200" DisplayMemberBinding="{Binding IsAdmin}"/>
<GridViewColumn Header="Mitarbeiter Status " Width="200" DisplayMemberBinding="{Binding Status, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<GridViewColumn Header="Mandantory " Width="200" DisplayMemberBinding="{Binding IsMandatory, Mode=TwoWay}"/>
</GridView>
</ListView.View>
</ListView>
</Grid>

Adjust height/position of multiple listviews so that content is aligned

I'm designing an application where I need to position multiple ListViews in a way that the content is aligned like this (simplified):
What I have:
The outer layout is a Grid (black)
The ListView (grey) on the left has a small header
The ListViews (grey) on the right are generated in an ItemsControl and have a fairly large header (vertical text). Also, they are part of a UserControl with additional content above them (not shown here)
What I want:
The contents (red) of all ListViews should be aligned and start at the same height (blue line)
I DON'T want to set the headers (green) to have the same height, because that would waste much space due to the large height difference.
The only solution I can think of is to calculate the height of all elements above the ListViews and the height of the headers, and then change the height of the upper Grid row so that the contents start at the same height. But that seems rather tedious, error prone and clumsy to me.
Is there a more elegant solution, maybe involving SharedGroupSize or binding the height property?
XAML for the overall layout:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<local:SomeControl1 x:Name="generalSettingsControl" Grid.Column="0" Grid.Row="0" />
<ListView ItemsSource="{Binding FirstList}">
<ListView.View>
<GridView>
<GridViewColumn Header="Name"
DisplayMemberBinding="{Binding CombinedName}" />
<GridViewColumn Header="ID"
DisplayMemberBinding="{Binding ID}" />
</GridView>
</ListView.View>
</ListView>
<ItemsControl Grid.Column="1" Grid.RowSpan="2" ItemsSource="{Binding Samples}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:ListViewUserControl DataContext="{Binding }" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
XAML for the ListViews in the ItemsControl :
<UserControl.Resources>
<Style x:Key="verticalGridViewColumnHeader" TargetType="GridViewColumnHeader">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock TextWrapping="Wrap" Text="{Binding}" FontWeight="Bold" Width="60"
VerticalAlignment="Center" TextAlignment="Center" HorizontalAlignment="Center">
<TextBlock.LayoutTransform>
<RotateTransform Angle="270" />
</TextBlock.LayoutTransform>
</TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="10" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox Text="Placeholder (TODO)" Grid.Column="0" />
<ListView x:Name="lvMeasurementsEdit"
ItemsSource="{Binding Measurements}"
Grid.Column="0"
Grid.Row="2">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Value 1" DisplayMemberBinding="{Binding Value1}"
HeaderContainerStyle="{StaticResource verticalGridViewColumnHeader}" Width="Auto" />
<GridViewColumn Header="Value 2" DisplayMemberBinding="{Binding Value2}"
HeaderContainerStyle="{StaticResource verticalGridViewColumnHeader}" Width="Auto" />
</GridView>
</ListView.View>
</ListView>
</Grid>

list view population using only xaml

I read a lot about the listView and still cant understand...
I defined the following listView with 5 column, the first is label and the rest are texboxes.
I need to add 13 rows that every textbox and labels needs to be bind to something diffrent.
So I understand that listViewItem wont do it because every object in the list, binds to somethin else..
Thank you for your help.
<ListView DockPanel.Dock="Top" Width="607" Height="400" Margin="10 0" HorizontalAlignment="Left"
ScrollViewer.HorizontalScrollBarVisibility="Hidden" BorderThickness="1">
<ListView.View>
<GridView>
<GridViewColumn Header="1" Width="120" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<Label/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="2" Width="120" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="3" Width="120" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="4" Width="120" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="5" Width="120" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
you really wane do something like this?
<Grid Height="100" HorizontalAlignment="Left" Margin="22,62,0,0" Name="listBox1" VerticalAlignment="Top" Width="607">
<Grid.ColumnDefinitions>
<ColumnDefinition Width='120'/>
<ColumnDefinition Width='120'/>
<ColumnDefinition Width='120'/>
<ColumnDefinition Width='120'/>
<ColumnDefinition Width='120'/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height='30'/>
<RowDefinition Height='30'/>
</Grid.RowDefinitions>
<!-- ROW 0-->
<Label Grid.Column='0' Grid.Row='0' Content=' your lable' Height="28"/>
<TextBox Grid.Column='1' Grid.Row='0' Text='Text01'/>
<TextBox Grid.Column='2' Grid.Row='0' Text='Text02'/>
<TextBox Grid.Column='3' Grid.Row='0' Text='Text03'/>
<TextBox Grid.Column='4' Grid.Row='0' Text='Text04'/>
<!--Row 1-->
<Label Grid.Column='0' Grid.Row='1' Content=' your lable' Height="28"/>
<TextBox Grid.Column='1' Grid.Row='1' Text='Text01'/>
<TextBox Grid.Column='2' Grid.Row='1' Text='Text02'/>
<TextBox Grid.Column='3' Grid.Row='1' Text='Text03'/>
<TextBox Grid.Column='4' Grid.Row='1' Text='Text04'/>
</Grid>
I finaly did a Grid in every item in the list like this:
<ListView DataContext="{Binding CurrentMonitorCalib}" Grid.Column="5" Grid.Row="3" Height="488" Width="444" ScrollViewer.HorizontalScrollBarVisibility="Hidden" BorderThickness="1">
<ListView.View>
<GridView>
<GridViewColumn Header="Cal Point" Width="80"/>
<GridViewColumn Header="Source" Width="90" />
<GridViewColumn Header="Failure Limit" Width="90" />
<GridViewColumn Header="Reference" Width="90" />
<GridViewColumn Header="# DaysLimit" Width="90" />
</GridView>
</ListView.View>
<ListViewItem>
<Grid Width="441" Margin="-359,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="81" />
<ColumnDefinition Width="91" />
<ColumnDefinition Width="91" />
<ColumnDefinition Width="91" />
<ColumnDefinition Width="91" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Label Content="Zero" Margin="5,0" />
<TextBox Grid.Column="1" Text="{Binding Path=ZeroSource, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Grid.Column="2" Text="{Binding Path=ZeroFailureLimit, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}" />
<TextBox Grid.Column="3" Text="{Binding Path=ZeroRef, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}" />
<TextBox Grid.Column="4" Text="{Binding Path=ZeroZNDays, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}" Margin="0,0,8,7" />
</Grid>
</ListViewItem>
<ListViewItem>
<Grid Width="442" Margin="-359,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="81" />
<ColumnDefinition Width="91" />
<ColumnDefinition Width="91" />
<ColumnDefinition Width="91" />
<ColumnDefinition Width="91" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Label Content="Span" Margin="5,0"/>
<TextBox Grid.Column="1" Text="{Binding Path=SpanSource, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Grid.Column="2" Text="{Binding Path=SpanFailureLimit, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}" />
<TextBox Grid.Column="3" Text="{Binding Path=SpanRef, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}" />
<TextBox Grid.Column="4" Text="{Binding Path=SpanNDays, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True}" Margin="0,0,8,7" />
</Grid>
</ListViewItem>
and so on.....
thanks for your help!

How to setup a grid as template for an Items control?

I'm trying to create an ItemsControl that uses a grid as its ItemsPanel in such a way that it has two columns, where the first columns width is the width of the widest item in that column, and has as may rows needed to display all the items
Basically, I want the following, but somehow within an ItemsControl so that I can bind to a collection of objects:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Label Content="{Binding Items[0].Header}"/>
<TextBox Text="{Binding Items[0].Content}" Grid.Column="1"/>
<Label Content="{Binding Items[1].Header}" Grid.Row="1"/>
<TextBox Text="{Binding Items[1].Content}" Grid.Row="1" Grid.Column="1"/>
<Label Content="{Binding Items[2].Header}" Grid.Row="2"/>
<TextBox Text="{Binding Items[2].Content}" Grid.Row="2" Grid.Column="1"/>
</Grid>
Edit : Rachels answer worked great, here is a working example.
(I moved the Grid.IsSharedSizeScope="True" to the ItemsPanel, not sure if Rachel meant to put it in the ItemTemplate (which didn't work))
namespace WpfApplication23
{
public partial class Window1 : Window
{
public List<Item> Items { get; set; }
public Window1()
{
Items = new List<Item>()
{
new Item(){ Header="Item0", Content="someVal" },
new Item(){ Header="Item1", Content="someVal" },
new Item(){ Header="Item267676", Content="someVal" },
new Item(){ Header="a", Content="someVal" },
new Item(){ Header="bbbbbbbbbbbbbbbbbbbbbbbbbb", Content="someVal" },
new Item(){ Header="ccccccc", Content="someVal" }
};
InitializeComponent();
DataContext = this;
}
}
public class Item
{
public string Header { get; set; }
public string Content { get; set; }
}
}
<Window x:Class="WpfApplication23.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Grid.IsSharedSizeScope="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="ColumnOne" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="{Binding Header}"/>
<TextBox Text="{Binding Content}" Grid.Column="1"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
There are multiple problems here for an ItemsControl:
Getting your first column to match the width of the largest item
Generating a dynamic number of rows
Generating more than one item for each iteration of the ItemsControl
The last one is really the biggest problem, because an ItemsControl wraps each ItemTemplate in a ContentPresenter, so there is no default way of creating more than one item in the panel for each Iteration of the ItemsControl. Your end result would look like this:
<Grid>
...
<ContentPresenter>
<Label Content="{Binding Items[0].Header}"/>
<TextBox Text="{Binding Items[0].Content}" Grid.Column="1"/>
</ContentPresenter>
<ContentPresenter>
<Label Content="{Binding Items[1].Header}" Grid.Row="1"/>
<TextBox Text="{Binding Items[1].Content}" Grid.Row="1" Grid.Column="1"/>
</ContentPresenter>
<ContentPresenter>
<Label Content="{Binding Items[2].Header}" Grid.Row="2"/>
<TextBox Text="{Binding Items[2].Content}" Grid.Row="2" Grid.Column="1"/>
</ContentPresenter>
</Grid>
My best suggestion would be to create an ItemTemplate that contains a 1x2 Grid, and use Grid.IsSharedSizeScope to make the width of the first column shared. (The ItemsPanelTemplate would remain the default StackPanel.)
This way, the end result would look like this:
<StackPanel>
<ContentPresenter>
<Grid IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="ColumnOne" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="{Binding Header}"/>
<TextBox Text="{Binding Content}" Grid.Column="1"/>
</Grid>
</ContentPresenter>
<ContentPresenter>
<Grid IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="ColumnOne" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="{Binding Header}"/>
<TextBox Text="{Binding Content}" Grid.Column="1"/>
</Grid>
</ContentPresenter>
...
</StackPanel>
You can use a ListView
<ListView ItemsSource="{Binding MyList}">
<ListView.View>
<GridView>
<GridView.ColumnHeaderContainerStyle>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="Visibility" Value="Collapsed" />
</Style>
</GridView.ColumnHeaderContainerStyle>
<GridViewColumn
Header=""
Width="Auto"
DisplayMemberBinding="{Binding Header}"/>
<GridViewColumn
Header=""
DisplayMemberBinding="{Binding Value}"/>
</GridView>
</ListView.View>
</ListView>
the ColumnHeaderContainerStyle hides the GridViewHeader

How to use gridsplitter on dynamic layout?

For the life of me I can't get the gridsplitter control to behave in the way I want.
In the below layout, I need a gridspliter to the right of each listview, that will expand or contract that listview and resize the other listviews appropriately.
The expanders and their (green) panels should not resize.
Please help! This control is driving me nuts.
MainWindow.xaml:
<Window x:Class="LayoutTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window2" Height="400" MinWidth="1000">
<Grid Name="root" SizeChanged="root_SizeChanged">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="200" Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition MinWidth="200" Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition MinWidth="200" Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ListView Grid.Column="0" MinWidth="100">
<ListViewItem>a</ListViewItem>
<ListViewItem>b</ListViewItem>
<ListViewItem>c</ListViewItem>
<ListViewItem>d</ListViewItem>
<ListView.View>
<GridView>
<GridViewColumn Header="a" Width="100" />
<GridViewColumn Header="b" Width="100" />
<GridViewColumn Header="c" Width="100" />
<GridViewColumn Header="d" Width="100" />
</GridView>
</ListView.View>
</ListView>
<Expander Name="xleft" Grid.Column="1" ExpandDirection="Left" Expanded="Expanded">
<Border MinWidth="300" Width="300" Background="Green" >
<TextBlock Text="{Binding ElementName=root,Path=ActualWidth}" />
</Border>
</Expander>
<ListView Grid.Column="2" MinWidth="100">
<ListViewItem>a</ListViewItem>
<ListViewItem>b</ListViewItem>
<ListViewItem>c</ListViewItem>
<ListViewItem>d</ListViewItem>
<ListView.View>
<GridView>
<GridViewColumn Header="a" Width="100" />
<GridViewColumn Header="b" Width="100" />
<GridViewColumn Header="c" Width="100" />
<GridViewColumn Header="d" Width="100" />
</GridView>
</ListView.View>
</ListView>
<Expander Name="xmiddle" Grid.Column="3" ExpandDirection="Left" Expanded="Expanded">
<Border MinWidth="300" Width="300" Background="Green" >
<TextBlock Text="{Binding ElementName=root,Path=ActualWidth}" />
</Border>
</Expander>
<ListView Grid.Column="4" MinWidth="100">
<ListViewItem>a</ListViewItem>
<ListViewItem>b</ListViewItem>
<ListViewItem>c</ListViewItem>
<ListViewItem>d</ListViewItem>
<ListView.View>
<GridView>
<GridViewColumn Header="a" Width="100" />
<GridViewColumn Header="b" Width="100" />
<GridViewColumn Header="c" Width="100" />
<GridViewColumn Header="d" Width="100" />
</GridView>
</ListView.View>
</ListView>
<Expander Name="xright" Grid.Column="5" ExpandDirection="Left" Expanded="Expanded">
<Border MinWidth="300" Width="300" Background="Green" >
<TextBlock Text="{Binding ElementName=root,Path=ActualWidth}" />
</Border>
</Expander>
</Grid>
</Window>
MainWindow.xaml.cs:
using System.Windows;
using System.Windows.Controls;
namespace LayoutTest
{
/// <summary>
/// Interaction logic for Window2.xaml
/// </summary>
public partial class MainWindow : Window
{
Expander[] expanders;
Expander priority;
public MainWindow()
{
InitializeComponent();
expanders = new Expander[] {xleft,xmiddle,xright};
}
private void Expanded(object sender, RoutedEventArgs e)
{
if (sender is Expander) priority = sender as Expander;
if (root.ActualWidth > this.ActualWidth)
{
foreach (Expander ep in expanders)
{
if (ep.IsExpanded && priority != null && !ep.Name.Equals(priority.Name) )
{
ep.IsExpanded = false;
break;
}
}
}
}
private void root_SizeChanged(object sender, SizeChangedEventArgs e)
{
Expanded(null,new RoutedEventArgs());
}
}
}
It's not ideal, but this is the solution I'm going with:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="100" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" MinWidth="100" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" MinWidth="100" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Background="Green">
</Border>
<Expander Name="ex1" Grid.Column="1" ExpandDirection="Left" Expanded="ex_Expanded">
<Border Background="Blue" MinWidth="200" MaxWidth="200">
</Border>
</Expander>
<GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Left" ResizeBehavior="PreviousAndNext" VerticalAlignment="Stretch" Background="Red" />
<GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Right" ResizeBehavior="PreviousAndNext" VerticalAlignment="Stretch" Background="Red" />
<Border Grid.Column="2" Background="Green">
</Border>
<Expander Name="ex2" Grid.Column="3" ExpandDirection="Left" Expanded="ex_Expanded">
<Border Background="Blue" MinWidth="200" MaxWidth="200">
</Border>
</Expander>
<GridSplitter Grid.Column="3" Width="5" HorizontalAlignment="Left" ResizeBehavior="PreviousAndNext" VerticalAlignment="Stretch" Background="Red" />
<GridSplitter Grid.Column="3" Width="5" HorizontalAlignment="Right" ResizeBehavior="PreviousAndNext" VerticalAlignment="Stretch" Background="Red" />
<Border Grid.Column="4" Background="Green">
</Border>
<Expander Name="ex3" Grid.Column="5" ExpandDirection="Left" Expanded="ex_Expanded">
<Border Background="Blue" MinWidth="200" MaxWidth="200">
</Border>
</Expander>
</Grid>

Resources