项目源集合上的WPF ItemsControl.ItemContainerStyle setter属性无法引用属性

时间:2015-02-04 15:34:03

标签: c# wpf xaml

编辑:嗯,看起来像对ChessPiece项目的绑定是一个Resharper问题 - 我把它关闭了,错误就消失了。难以置信的。

我一直在尝试将集合中的项目绑定到网格位置。我已经能够绑定一个集合并绘制项目,但在XAML中,我无法引用我需要的属性。

根据此示例:http://wpf.2000things.com/2011/12/21/455-using-itemcontainerstyle-to-bind-data-elements-in-a-collection-to-a-grid/

代码:

public class ChessPiece
{
    public string Text { get; set; }
    public int Row { get; set; } // 0..n-1
    public int Column { get; set; } // 0..n-1

    public ChessPiece(string text, int row, int col)
    {
        Text = text;
        Row = row;
        Column = col;
    }
}

public class MainViewModel : ViewModelBase
{

    public ObservableCollection<ChessPiece> ChessPieces { get; private set; }
    /// <summary>
    /// Initializes a new instance of the MainViewModel class.
    /// </summary>
    public MainViewModel()
    {
        ChessPieces = new ObservableCollection<ChessPiece>();
        ChessPieces.Add(new ChessPiece("QR-BLK", 1, 1));
        ChessPieces.Add(new ChessPiece("QN-BLK", 1, 2));
        ChessPieces.Add(new ChessPiece("QB-BLK", 0, 3));

        ////if (IsInDesignMode)
        ////{
        ////    // Code runs in Blend --> create design time data.
        ////}
        ////else
        ////{
        ////    // Code runs "for real"
        ////}
    }
}

XAML:

<Window x:Class="MVVMLightTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        DataContext="{Binding Main, Mode=OneWay, Source={StaticResource Locator}}" Height="550" Width="525">
    <Grid Margin="0,0,0,0">
        <ItemsControl ItemsSource="{Binding ChessPieces}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Grid ShowGridLines="True">
                        <Grid.RowDefinitions >
                            <RowDefinition Height="162.667"></RowDefinition>
                            <RowDefinition Height="171.333"></RowDefinition>
                            <RowDefinition Height="165.333"/>
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="162"></ColumnDefinition>
                            <ColumnDefinition Width="206">/>
                            <ColumnDefinition Width="263"/>
                        </Grid.ColumnDefinitions>
                    </Grid>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Label Content="{Binding Text}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
            <ItemsControl.ItemContainerStyle>
                <Style>
                    <Setter Property="Grid.Row" Value="{Binding Row}"/>
                    <Setter Property="Grid.Column" Value="{Binding Column}"/>
                </Style>
            </ItemsControl.ItemContainerStyle>
        </ItemsControl>
    </Grid>
</Window>

在主视图模型中,我有一个可观察到的国际象棋集合,我用新的国际象棋填充。

我可以绑定到XAML其他级别的Row属性,而不是在我试图将它绑定到网格位置的Style setter中 - 可以绑定集合,但不能绑定到单个项目。

任何帮助都将非常感谢!

1 个答案:

答案 0 :(得分:0)

这与简单的绑定几乎不可能。容器,而不是模板生成的控件,是您需要设置行/网格所需的,并且到达它是有趣。

我的解决方案,虽然丑陋是创建我的自己的特殊Grid,并使用ArrangeOverride

class DynamicGrid : Grid
{
    protected override System.Windows.Size ArrangeOverride(System.Windows.Size arrangeSize)
    {
        UIElementCollection elements = base.InternalChildren;
        for (int i = 0; i < elements.Count; i++)
        {
            elements[i].SetValue(Grid.RowProperty, correctRow);
        }

        return base.ArrangeOverride(arrangeSize);
    }
}

显然,仅仅是结构,您必须确定获取将行/列设置为此对象所需的数据的最佳方法。好消息是,当您将此Grid设置为ItemsPanelTemplate时,您可以定期绑定到您在自定义Grid上设置的任何DP:

     <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <local:DynamicGrid />
            </ItemsPanelTemplate>
      </ItemsControl.ItemsPanel>

当然,获取正确的数据将是非常重要的,但与在里面模板中设置容器Grid.Row属性相比,它更容易。