简体   繁体   中英

How to assign grid row and column index dynamically

I am trying to add user controls to the Grid and I am trying to set the Grid.Column and Grid.Row property in the DataTemplate but it does not have any effect on the rendering. Can someone help to point out what could be wrong in the code below.

I have the main window with the following code:

<ItemsControl ItemsSource="{Binding Controls}">
    <ItemsControl.ItemsPanel >
        <ItemsPanelTemplate>
            <Grid Name="MainGrid">
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>    
            </Grid>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <AppControls:TagInfo Grid.Row="{Binding RowIndex}"
                                 Grid.Column="{Binding ColumnIndex}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

TagInfo.xaml.cs

public partial class TagInfo : UserControl
{
    public TagInfo()
    {
        InitializeComponent();
    }

    public int RowIndex { get; set; }

    public int ColumnIndex { get; set; }
}

TagInfo.xaml

<UserControl x:Class="DataSimulator.WPF.Controls.TagInfo"
             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" 
             mc:Ignorable="d" Height="258" Width="302"
             DataContext="{Binding Main, Source={StaticResource Locator}}">
    <Grid Margin="2,2,2,2">
        <Grid.RowDefinitions>
            <RowDefinition Height="40"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Row="0" Grid.Column="0" Text="Tag"/>
        <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding TagInfo.TagName}"/>

        <TextBlock Grid.Row="1" Grid.Column="0" Text="High High"/>
        <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding TagInfo.HighHigh}"/>

        <TextBlock Grid.Row="2" Grid.Column="0" Text="High"/>
        <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding TagInfo.High}"/>

        <TextBlock Grid.Row="3" Grid.Column="0" Text="Low Low"/>
        <TextBox Grid.Row="3" Grid.Column="1" Text="{Binding TagInfo.LowLow}"/>

        <TextBlock Grid.Row="4" Grid.Column="0" Text="Low"/>
        <TextBox Grid.Row="4" Grid.Column="1" Text="{Binding TagInfo.Low}"/>

        <TextBlock Grid.Row="5" Grid.Column="0" Text="Range Start"/>
        <TextBox Grid.Row="5" Grid.Column="1" Text="{Binding TagInfo.RangeStart}"/>

        <TextBlock Grid.Row="6" Grid.Column="0" Text="Range End"/>
        <TextBox Grid.Row="6" Grid.Column="1" Text="{Binding TagInfo.RangeEnd}"/>

        <Button Grid.Row="7" Grid.Column="0" Grid.ColumnSpan="2" Content="Save"/>
    </Grid>
</UserControl>

ViewModel

private ObservableCollection<Controls.TagInfo> _controls
        = new ObservableCollection<Controls.TagInfo>();

public ObservableCollection<Controls.TagInfo> Controls
{
    get { return _controls; }
    set { _controls = value; }
}

private void AddControl()
{
    if(currentRow == 3)
    {
        currentRow = 0;
    }

    if(currentColumn == 3)
    {
        currentColumn = 0;
        currentRow++;
    }

    var tagInfoUserControl = new Controls.TagInfo();
    tagInfoUserControl.RowIndex = currentRow;
    tagInfoUserControl.ColumnIndex = currentColumn++;
    _controls.Add(tagInfoUserControl);
}

I am trying to add user controls to the grid and I am trying to set the Grid.Column and Grid.Row property in the data template but it does not have any effect on the rendering

We can't do the attached property binding in a DataTemplate , creating a style for your UserControl in ItemsControl.ItemContainerStyle can make it work:

<ItemsControl ItemsSource="{Binding Controls}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid Name="MainGrid">
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
            </Grid>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="AppControls:TagInfo">
            <Setter Property="Grid.Row" Value="{Binding RowIndex}"/>
            <Setter Property="Grid.Column" Value="{Binding ColumnIndex}"/>
        </Style>
    </ItemsControl.ItemContainerStyle>
</ItemsControl>

Screenshot:

在此处输入图片说明

when all columns and rows have to be of equal size and elements are consequtive, it is probably simpler to use UniformGrid . Rows and Columns properties support binding.

<ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
        <UniformGrid Name="MainGrid" Rows="4" Columns="4"/>
    </ItemsPanelTemplate>
</ItemsControl.ItemsPanel>

here is a nice example of Grid ItemsPanel here: WPF Grid as ItemsPanel for a list dynamically bound to an ItemsControl

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM