如何动态分配网格行和列索引

时间:2016-06-08 02:49:14

标签: c# .net wpf mvvm mvvm-light

我正在尝试向Grid添加用户控件,我正在尝试在DataTemplate中设置Grid.ColumnGrid.Row属性,但它对渲染没有任何影响。有人可以帮助指出下面代码中可能出现的问题。

我的主窗口包含以下代码:

<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>

视图模型

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);
}

2 个答案:

答案 0 :(得分:1)

  

我正在尝试将用户控件添加到网格中,我正在尝试在数据模板中设置Grid.Column和Grid.Row属性,但它对渲染没有任何影响

我们无法在DataTemplate中执行附加的属性绑定,在 ItemsControl.ItemContainerStyle 中为您的UserControl创建样式可以使其正常工作:

<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>

<强>截图:

enter image description here

答案 1 :(得分:0)

当所有列和行必须具有相同的大小且元素是连续的时,使用UniformGrid可能更简单。行和列属性支持绑定。

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

这里有一个很好的Grid ItemsPanel示例:WPF Grid as ItemsPanel for a list dynamically bound to an ItemsControl