wpf listbox and datatemplate with grid inside

2019-04-02 03:42发布

问题:

I have a following question. I want to have ListBox with DataTemplate as Grid. This grid has 2 two columns. I want to set first column width to 3* and another to *. How to do this? I will copy my code.

<ListBox x:Name="commandListbox" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" HorizontalAlignment="Stretch">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="3*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>

                <TextBlock Grid.Column="0" Text="{Binding}"/>
                <TextBlock Grid.Column="1" Text="icon" />
           </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>                
</ListBox>

回答1:

Better to store the template in resources:

<Window.Resources>
  <DataTemplate x:Key="DefaultTemplate">
    <Grid x:Name="GridItem" Width="200">
       <Grid.ColumnDefinitions>
           <ColumnDefinition Width="Auto" />
           <ColumnDefinition Width="Auto" />
       </Grid.ColumnDefinitions>

       <TextBlock x:Name="Parameter" Grid.Column="1" Text="{Binding Path=Name}" Margin="5,1,0,0" />
       <TextBlock x:Name="Value" Grid.Column="2" Text="{Binding Path=Age}" Margin="85,1,0,0" />

       <Line x:Name="Separator" X1="0" X2="0" Y1="0" Y2="20" SnapsToDevicePixels="True" Grid.Column="1" Stroke="Black" StrokeThickness="2" Margin="50,0,0,0" HorizontalAlignment="Left" />
   </Grid>
 </DataTemplate>
</Window.Resources>

ListBox define:

<ListBox Name="MyListBox" ItemTemplate="{StaticResource DefaultTemplate}" />

In code C#:

public class Person
{
  public string Name
  {
    get;
    set;
  }

 public int Age
 {
   get;
   set;
 }
}

Define ObservableCollection:

private ObservableCollection<Person> MyListBoxData = new ObservableCollection<Person>();

And add items on collection:

MyListBoxData.Add(new Person()
{
  Name = "Nick",
  Age = 21,
});

MyListBoxData.Add(new Person()
{
  Name = "Adam",
  Age = 11,
});

MyListBox.ItemsSource = MyListBoxData;

EDITED:

Then set Width="3*", Width="*" and Margin="-WidthGrid" of the first TextBlock:

<Grid x:Name="GridItem" Width="300">
 <Grid.ColumnDefinitions>
  <ColumnDefinition Width="3*" />
  <ColumnDefinition Width="*" />
 </Grid.ColumnDefinitions>

 <TextBlock x:Name="Parameter" Grid.Column="1" Text="{Binding Path=Name}" Margin="-220,0,0,0" />
 <TextBlock x:Name="Value" Grid.Column="2" Text="{Binding Path=Age}" Margin="0,0,0,0" />
</Grid>


回答2:

Use IsSharedSizeScope to share column sizing across the generated grids, for Auto widths (can't be done for * sizing):

via http://wpftutorial.net/DataTemplates.html

<ListBox ItemsSource="{Binding}" BorderBrush="Transparent" 
     Grid.IsSharedSizeScope="True"
     HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
    <DataTemplate>
        <Grid Margin="4">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" SharedSizeGroup="Key" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding Name}" FontWeight="Bold"  />
            <TextBox Grid.Column="1" Text="{Binding Value }" />
        </Grid>
    </DataTemplate>
</ListBox.ItemTemplate>

See MSDN remarks

Columns and rows participating in size sharing do not respect Star sizing. In this scenario, Star sizing is treated as Auto. Grid size sharing does not work if IsSharedSizeScope is set to true within a resource template, and a SharedSizeGroup is defined outside of that template.



回答3:

<ListBox x:Name="commandListbox" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" HorizontalAlignment="Stretch">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="0.75*" />
                    <ColumnDefinition Width="0.25*" />
                </Grid.ColumnDefinitions>

                <TextBlock Grid.Column="0" Text="{Binding}"/>
                <TextBlock Grid.Column="1" Text="icon" />
           </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>                
</ListBox>

If I understand you correctly, you are looking for 3/4th space for 1st column and 1/4th space for 2nd column. Setting the width in the above format must be solving the problem.

Hope it solves.