WPF Sorting ItemsControl Binding [duplicate] - c#

This question already has answers here:
WPF Sorting an ObservableCollection de-selects a ComboBox
(2 answers)
Closed 5 years ago.
I am currently trying to sort a ItemsControl by Name. Currently I have the list printing out but can't seem to order it on the Views side. I have the ability to order it on the Control or model side but want it to work from the view.
My ItemsControl has a binding to AllJobTypes (a list of class JobTypes). JobTypes has a property called Name that I would like to sort in the view.
I have some debug code in the XAML that Prints out the count of each object. The first 2 print out 'fail' and the last one works correctly. What can i do to order AllJobTypes on the view side?
<UserControl.Resources>
<converters:JobTypeCreditUnionCountConverter x:Key="JobTypeCreditUnionCountConverter" />
<CollectionViewSource x:Key="cvs" Source="{Binding RelativeSource={RelativeSource
AncestorType=UserControl}, Path=AllJobTypes}">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="Name"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</UserControl.Resources>
<StackPanel>
<Label Foreground="SteelBlue" FontSize="20" FontWeight="Bold">Job Types</Label>
<Label Content="{Binding AllJobTypes.Count, FallbackValue='fail'}" /> //Fail
<Label Content="{Binding cvs.Count, FallbackValue='fail'}" /> //Fail
<Label Content="{Binding RelativeSource={RelativeSource
AncestorType=UserControl}, Path=AllJobTypes}" /> //(Collection
<ItemsControl ItemsSource="{Binding cvs}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="6*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="" />
<TextBox Grid.Column="1" Text="{Binding Name}" IsEnabled="False" />

Try:
<ItemsControl ItemsSource="{Binding Source={StaticResource cvs}}" >

Related

How to get webview2 control in list control

I want to pass the webview2 control on the page to the ViewModel after clicking the button.
The following is part of the code for xaml:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel>
<!--Click the button "Button_single", and the value of parameter can be obtained from ViewModel as Microsoft.Web.WebView2.Wpf.WebView2 type-->
<Button Command="{Binding BtnCommand1}" CommandParameter="{Binding ElementName=webView_single}">Button_single</Button>
<!--Click the button "Button_list", and the value of parameter obtained from ViewModel is null. Why?-->
<Button Command="{Binding BtnCommand1}" CommandParameter="{Binding ElementName=webView_list}">Button_list</Button>
<webview2:WebView2 Name="webView_single" Source="https://www.google.com/" Grid.Row="1">
<behaviour:Interaction.Triggers>
<behaviour:EventTrigger EventName="NavigationCompleted">
<behaviour:CallMethodAction TargetObject="{Binding}" MethodName="webView2_NavigationCompleted" />
</behaviour:EventTrigger>
</behaviour:Interaction.Triggers>
</webview2:WebView2>
</StackPanel>
<ScrollViewer Grid.Row="2" >
<ItemsControl Grid.Row="1" ItemsSource="{Binding AccountDtos}" HorizontalAlignment="Center">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<md:TransitioningContent OpeningEffect="{md:TransitionEffect Kind=ExpandIn}" >
<Grid Width="600" MinHeight="800" MaxHeight="250" Margin="8" >
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Border CornerRadius="4" Grid.RowSpan="5" Background="#7F7F7F" />
<StackPanel Orientation="Horizontal">
<TextBlock Text="UserName:" />
<TextBlock Padding="5,0" Text="{Binding UserName}" />
<TextBlock Text="Password:" />
<TextBlock Padding="5,0" Text="{Binding Password}" />
</StackPanel>
<webview2:WebView2 Name="webView_list" Source="https://www.google.com/" Grid.Row="1">
<behaviour:Interaction.Triggers>
<behaviour:EventTrigger EventName="NavigationCompleted">
<behaviour:CallMethodAction TargetObject="{Binding}" MethodName="webView2_NavigationCompleted" />
</behaviour:EventTrigger>
</behaviour:Interaction.Triggers>
</webview2:WebView2>
</Grid>
</md:TransitioningContent>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
I want to pass the webview2 control on the page to the ViewModel after clicking the button.
The following is part of the code for xaml:
public DelegateCommand<object> BtnCommand1 { get => new DelegateCommand<object>(Execute1); }
private void Execute1(object parameter)
{
//In the xaml page, if you click the button "Button_single", you can get the parameter value of Microsoft.Web.WebView2.Wpf.WebView2 type
//If you click the button "Button_list", the value of parameter is null. Why and how can it not be null?
Console.Write(parameter);
}
I want to get the webView control in the list control in the ViewModel. How should I write this code?
(This question Passing a Different button in Command Parameter Wpf Similar to my question, but different)
There are two reasons the webView_list commandparameter cannot work.
The first is conceptual. There are going to be a list of those WebView2s rather than just one. How's it supposed to know which one it is to reference?
You know if you have a list of anything in c# then you'd have to reference by index or something which one in the list you want.
The same would be true for xaml. You'd need to tell it to go look at row 0 or 1 or 2 or whatever.
There is another complication though. WPF has the concept of namescopes. All the controls directly in the grid of your window are in the same namescope.
When you have templates and in particular lists of things that becomes a bit more complicated.
Let's think about this from the bottom up though.
You've named a control webView_list. This is in an itemtemplate. So when you have 4 items you will have 4 WebView2s. But it will not error. Somehow those 4 named controls do not collide with one another.
This is because each of those items produced from that itemtemplate have their own namescope. The first item has a namescope of it's own, the second has it's own namescope etc.
You cannot just use elementname to reference something in a different namescope. So you can't get at a specific webview2 in that list using elementname from outside the item it's in.
In any case, you need some way to tell which item.
You could use selecteditem if this was a listbox.
An itemscontrol has no selection though. To get at your webview2 in an item the usual thing to do would be to put the button in the itemtemplate and the same namescope. That could then use relativesource to get to the command in the parent datacontext. Something like:
<ItemsControl.ItemTemplate>
<DataTemplate>
<md:TransitioningContent OpeningEffect="{md:TransitionEffect Kind=ExpandIn}" >
<Grid Width="600" MinHeight="800" MaxHeight="250" Margin="8" >
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Border CornerRadius="4" Grid.RowSpan="5" Background="#7F7F7F" />
<StackPanel Orientation="Horizontal">
<TextBlock Text="UserName:" />
<TextBlock Padding="5,0" Text="{Binding UserName}" />
<TextBlock Text="Password:" />
<TextBlock Padding="5,0" Text="{Binding Password}" />
</StackPanel>
<Button Command="{Binding DataContext.BtnCommand1, RelativeSource={RelativeSource AncestorType ItemsControl}}"
CommandParameter="{Binding ElementName=webView_list}" Grid.Row="2">Button_list</Button>
<webview2:WebView2 Name="webView_list" Source="https://www.google.com/" Grid.Row="2">
<behaviour:Interaction.Triggers>
<behaviour:EventTrigger EventName="NavigationCompleted">
<behaviour:CallMethodAction TargetObject="{Binding}" MethodName="webView2_NavigationCompleted" />
</behaviour:EventTrigger>
</behaviour:Interaction.Triggers>
</webview2:WebView2>
</Grid>
</md:TransitioningContent>
</DataTemplate>
</ItemsControl.ItemTemplate>

How to auto height set to itemscontrol in wpf?

I have using the itemscontrol in WPF, I have given the dictionary collection as itemsource for itemscontrol. In this dictionary collection, will be used key and observablecollection. Different items will be in observablecollection of each dictionary items. so, when i'm given an itemsource it will be taken same height.
see the code:
<ItemsControl
Grid.Row="1"
Height="Auto"
ItemsSource="{Binding Values}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
IsItemsHost="True"
Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<GroupBox
MinWidth="303"
Margin="5,0,0,0">
<ItemsControl Margin="20,5,0,5">
<ItemsControl.Resources>
<CollectionViewSource x:Key="Collection" Source="{Binding Value}" />
<DataTemplate DataType="{x:Type Model:Sensor}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label
Grid.Column="1"
Content="{Binding Name}"
FontFamily="SegoeUI-Semibold"
FontSize="12"
FontWeight="SemiBold" />
<Label
Grid.Column="2"
HorizontalContentAlignment="Center"
Content="{Binding Value}"
FontFamily="SegoeUI"
FontSize="12" />
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type Model:DigitalInput}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label
Grid.Column="1"
Content="{Binding Name}"
FontFamily="SegoeUI-Semibold"
FontSize="12"
FontWeight="SemiBold" />
<Label
Grid.Column="2"
HorizontalContentAlignment="Center"
Content="{Binding InputState}"
FontFamily="SegoeUI"
FontSize="12" />
</Grid>
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource Collection}}" />
</CompositeCollection>
</ItemsControl.ItemsSource>
</ItemsControl>
</GroupBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
see the class code:
private Dictionary<string, ObservableCollection<IValue>> values;
public Dictionary<string, ObservableCollection<IValue>> Values
{
get { return values; }
set { values = value; }
}
Current output:
Expected output:
I need to group the items as an expected output, so could you please provide any solution to achieve that?
This is how WrapPanel works. If you set Horizontal all items in row will have same height and it wraps elements to the next row.
You can try specifying Orientation="Vertical" for your WrapPanel, but not quite sure if it suits you. In this case all elements in column will have same width.
Otherwise you don't need either WrapPanel or UniformGrid, you need different panel which is called StaggeredPanel. Source code for uwp can be easily used in WPF, I just checked it.
Only had to rewrite one line which is not a big deal with the following answer: RegisterPropertyChangedCallback(Panel.HorizontalAlignmentProperty, OnHorizontalAlignmentChanged);
An explanation for similar control can be found on codeproject (Called VariableSizedWrapGrid). But I checked it and it has errors somewhere.
On ios it's called mosaic view or StaggeredLayoutManager for RecyclerView on Android.
Instead of WrapPanel, try a UniformGrid:
<UniformGrid Columns="1" IsItemsHost="True" />
Also, I'm not sure about the Height="Auto" setting. Remove it. The setting belongs to the RowDefinition of the grid.

TabItem DataTemplate with binding

I have a TabControl in my app. I'd like to have as many TabItems as many entries are in my dictionary.
Here's my dictionary:
public Dictionary<string , ObservableCollection<PerformanceCounter>> Counters
{
get { return _Counters; }
}
Dictionary<string, ObservableCollection<PerformanceCounter>> _Counters = new Dictionary<string , ObservableCollection<PerformanceCounter>>();
Every entry has a string key and ObservableCollection of PerformanceCounter objects. Important thing is the fact that every PerformanceCounter object has properties: CounterName and InstanceName - I'll need these two to display them.
Now, to my XAML:
<TabItem Header="Memory">
<Grid Name="RAMGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListBox Name="RAMListBox" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" ItemsSource="{Binding Memory, Mode=OneWay}" SelectionMode="Multiple" BorderThickness="1" BorderBrush="#FF8B8B8B" SelectionChanged="RAMListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<Run Text="{Binding CounterName, Mode=OneWay}" />
<Run Text="{Binding InstanceName, Mode=OneWay}" />
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Name="RAMSelectAllButton" Margin="0,10,0,0" Grid.Column="0" Grid.Row="1" Click="RAMSelectAllButton_Click" >
<TextBlock Text="SELECT ALL"/>
</Button>
<Button Name="RAMUnSelectAllButton" Margin="0,10,0,0" Grid.Column="1" Grid.Row="1" Click="RAMUnSelectAllButton_Click" >
<TextBlock Text="UNSELECT ALL"/>
</Button>
</Grid>
</TabItem>
That's what I did and, as you might already know, it does not work. The above code is only for one entry of my dictionary, where the key is "Memory".
In my code I set DataContext:
this.DataContext = appData.Counters;
appData.Counters is that dictionary I presented at the beginning.
Here's what I'd like to achieve:
No matter how many entries there are in my dictionary, my TabControl would display TabItem for each of them.
Each TabItem has a ListBox and 2 buttons. I'll need too be able to access those (in order to clear the list and to have click event for each button).
I really don't know how to do it, I hope you can help me out.
Binding TabControl to items in Dictionary:
<Window.Resources>
<DataTemplate x:Key="templateForTheContent" >
<StackPanel>
<ListBox Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0"
ItemsSource="{Binding Value, Mode=OneWay}"
SelectionMode="Multiple"
BorderThickness="1" BorderBrush="#FF8B8B8B">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<Run Text="{Binding CounterName, Mode=OneWay}" />
<Run Text="{Binding InstanceName, Mode=OneWay}" />
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="templateForTheHeader" >
<TextBlock Text="{Binding Key}"/>
</DataTemplate>
</Window.Resources>
<Grid>
<TabControl TabStripPlacement="Left" VerticalAlignment="Stretch" HorizontalContentAlignment="Stretch"
ItemsSource="{Binding Counters}"
ContentTemplate="{StaticResource templateForTheContent}"
ItemTemplate="{StaticResource templateForTheHeader}">
</TabControl>
</Grid>
Now, Dictionary is not observable so if items will be added/removed during runtime, you may consider using something like ObservableDictionary instead
Create a ViewModel-class containing:
your Dictionary
two ICommand-Implementations for your Buttons
then
set the ViewModel-class as DataContext of the TabControl
set Counters as the ItemSource of the TabControl
reuse your XAML-Code defined within the TabItem and use it as
the Tabcontrol.ContentTemplate
Bind .Command of your Buttons to the ICommands in your ViewModel using RelativeSource
see for samples:
ContentTemplate: https://wpf.2000things.com/tag/tabcontrol/
ICommand https://stackoverflow.com/a/1468830/4919708
RelativeSource: https://stackoverflow.com/a/84317/4919708
As i said in one of the comments above I changed my Dictionary to this:
//list of all counters
public ObservableCollection<ObservableCollection<PerformanceCounter>> Counters
{
get { return _Counters; }
}
ObservableCollection<ObservableCollection<PerformanceCounter>> _Counters = new ObservableCollection<ObservableCollection<PerformanceCounter>>();
i used #Arie's solution to write this XAML:
<DataTemplate x:Key="templateForTheContent" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListBox Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0"
ItemsSource="{Binding}"
SelectionMode="Multiple"
BorderThickness="1" BorderBrush="#FF8B8B8B">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<Run Text="{Binding CounterName, Mode=OneWay}" />
<Run Text="{Binding InstanceName, Mode=OneWay}" />
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Name="RAMSelectAllButton" Margin="0,10,0,0" Grid.Column="0" Grid.Row="1" >
<TextBlock Text="SELECT ALL"/>
</Button>
<Button Name="RAMUnSelectAllButton" Margin="0,10,0,0" Grid.Column="1" Grid.Row="1" >
<TextBlock Text="UNSELECT ALL"/>
</Button>
</Grid>
</DataTemplate>
<DataTemplate x:Key="templateForTheHeader" >
<TextBlock Text="{Binding CategoryName}"/>
</DataTemplate>
</Window.Resources>
It displays correctly as many Tabs as I add entries to my Class ObservableCollection in the code behind.
Now i have a new problem: I don't know how to access each listBox from each Tab. i need to be able to read the list of selected objects.

How to freeze a column in Grid and make it always shown in client area of a WPF user control

I searched in stackoverflow, and there is a property FrozenColumnCount for DataGrid, but Grid control doesn't have that property.
We have a Grid with 2 columns. Now, we need to freeze the last column in a grid, and make it always shown in the client area of the user control. otherwise, if the data (such as text) in first column is too long, customer has to use mouse to drag the horizon scroll bar to show the 2nd column.
We want customer can always see the data in 2nd column, so I wonder if we could freeze the specified column.
Update 1: I paste my code for the tree view control.
<HierarchicalDataTemplate x:Uid="HierarchicalDataTemplate_1" x:Key="MyPaletteMyTestTreeCell"
ItemsSource="{Binding Converter={StaticResource MyTestDataAccessor}}"
ItemTemplateSelector="{StaticResource MyTestDataAccessor}">
<ContentControl x:Uid="ContentControl_1" MouseDoubleClick="Item_MouseDoubleClick" ContextMenu="{StaticResource TreeListViewItemContextMenu}" MouseRightButtonDown="MRClick" Focusable="False">
<Grid x:Uid="Grid_2" Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Uid="ColumnDefinition_3" />
<ColumnDefinition x:Uid="ColumnDefinition_2" Width="Auto" />
</Grid.ColumnDefinitions>
<Grid x:Uid="Grid_3" Grid.Column="0">
<StackPanel x:Uid="StackPanel_3" HorizontalAlignment="Left" Orientation="Horizontal">
<pc:ThemedImage x:Uid="Image_4"
LightSource="{Binding CategoryId, Converter={StaticResource LightMyTestIconConverter}, Mode=OneWay}"
DarkSource="{Binding CategoryId, Converter={StaticResource DarkMyTestIconConverter}, Mode=OneWay}"
Width="16" Height="16"
Margin="0,1,0,1"
VerticalAlignment="Center"/>
<TextBlock x:Uid="TextBlock_13" Text="{Binding Name}" VerticalAlignment="Center" Margin="3,0,0,1" TextTrimming="CharacterEllipsis" TextWrapping="NoWrap"/>
</StackPanel>
</Grid>
<Grid x:Uid="Grid_4" Grid.Column="1">
<CheckBox x:Uid="CheckBox_3" HorizontalAlignment="Right" Click="CheckBox_Click" Grid.Column="1" Style="{StaticResource MyPaletteMyTestVisibilityStyle}" ToolTip="On/Off" Focusable="False">
<CheckBox.IsChecked>
<Binding x:Uid="Binding_1" Converter="{StaticResource MyTestDataAccessor}" Path="Visibility" Mode="OneWay">
<Binding.ConverterParameter>
<FrameworkElement x:Uid="FrameworkElement_1" DataContext="{TemplateBinding DataContext}" Tag="Visibility"/>
</Binding.ConverterParameter>
</Binding>
</CheckBox.IsChecked>
<CheckBox.IsEnabled>
<Binding x:Uid="Binding_2" Converter="{StaticResource MyTestDataAccessor}" Path="Visibility" Mode="OneWay">
<Binding.ConverterParameter>
<FrameworkElement x:Uid="FrameworkElement_2" DataContext="{TemplateBinding DataContext}" Tag="Enabled"/>
</Binding.ConverterParameter>
</Binding>
</CheckBox.IsEnabled>
</CheckBox>
</Grid>
</Grid>
</ContentControl>
</HierarchicalDataTemplate>
SOLUTION:
I found the cause. I have specified a horizon scroll bar for it.
So, when I removed it and use the code above, it can work as expected.
thanks a lot.
Clearly, you're not thinking about this correctly. You just need to put the column that you want to 'freeze' into a column of an outer Grid. Try something this:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<!-- Your other controls -->
</Grid>
<Grid Grid.Column="1" Name="FrozenColumn">
<!-- Your frozen controls -->
</Grid>
</Grid>

Design Xaml grid with height = 100% and minimum row height size

Here's the problem. I have a grid with some data written in xaml:
<ItemsControl x:Name="ItemsControl" ItemsSource="{Binding Path=MyObjectCollection, UpdateSourceTrigger = PropertyChanged}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="27"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MaxHeight="75" MinHeight="30"></RowDefinition>
</Grid.RowDefinitions>
<Label Name="LabelNumber" Content="{Binding ObjectID}" Grid.Column="0" Style="{StaticResource MyStyleLabel}" />
<control:FocusMeterControl x:Name="HorizontalFocusMeterControl" Value="{Binding ObjectProperty}" Height="Auto" Grid.Column="1" />
<Button Name="RemoveObject" Content="-" Grid.Column="2" Margin="5,0,0,0" Click="ButtonBase_OnClick" Tag="{Binding Point}" Style="{StaticResource MyStyleButton}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
As you can see I'm creating a new grid for each member in my "MyObjectCollection". Ideally I think I should just create one row instead since this would make my next problem - the real problem easier.
However, I have not found any good way to do this in xaml if even possible. Is this possible without populating the collection manually from c# and setting a row-property in my objects manually in order to do something like this
<Label Name="LabelNumber" Grid.Row="{Binding ManuallyCalculatedRowID}" ... />
My primary problem is that I would like the grid/rows to all be equally high and if possible fill out the parent window. If the parent window is way too large MaxHeight should apply and I would just like some empty space below.
The parent control is a Windows Form ElementHost if that makes any difference.
Please let me know if you need any additional info.
To make all rows of equal hight we can use ItemsPanelTemplate and set it to UniformGrid that will take care of equal sizing problem:
<ItemsControl x:Name="ItemsControl" ItemsSource="{Binding Path=MyObjectCollection, UpdateSourceTrigger = PropertyChanged}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="27"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Label Name="LabelNumber" Content="{Binding ObjectID}" Grid.Column="0" Style="{StaticResource MyStyleLabel}" />
<control:FocusMeterControl x:Name="HorizontalFocusMeterControl" Value="{Binding ObjectProperty}" Height="Auto" Grid.Column="1" />
<Button Name="RemoveObject" Content="-" Grid.Column="2" Margin="5,0,0,0" Click="ButtonBase_OnClick" Tag="{Binding Point}" Style="{StaticResource MyStyleButton}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Note that I removed row definition in ItemTemplate to lift vertical size restrictions for items. Not sure if that answers your question but that can be good starting point on the road to solution.

Categories