Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在ItemsControl中定位项目_C#_Wpf_Itemscontrol - Fatal编程技术网

C# 在ItemsControl中定位项目

C# 在ItemsControl中定位项目,c#,wpf,itemscontrol,C#,Wpf,Itemscontrol,我有一个ItemsControl绑定到如下数据: <ItemsControl Name="MainPanel" > <ItemsControl.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Definition}" TextWrapping="Wrap"/> </DataTemplate> </It

我有一个ItemsControl绑定到如下数据:

<ItemsControl Name="MainPanel" >
    <ItemsControl.ItemTemplate>
        <DataTemplate>
           <TextBlock Text="{Binding Definition}" TextWrapping="Wrap"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
在我的数据模型中,每个项目都有一个y坐标,用于在屏幕上垂直定位项目,由于文本包装,每个项目的高度都是可变的

我需要将每个项目放置在y坐标上,除非它与上一个项目重叠,在这种情况下,它被放置在上一个项目的下方

我想用保证金属性来做这件事,但实际上并不是那么简单

有没有关于如何继续的想法?

我认为更改TextBlock.Margin.Top是一个简单的方法

    <ItemsControl ItemsSource="your model collection"
             ScrollViewer.HorizontalScrollBarVisibility="Disabled">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <!-- Need ItemsControl for calculation. -->
                <TextBlock Text="{Binding Text}" TextWrapping="Wrap"
                           Tag="{Binding RelativeSource={RelativeSource AncestorType=ItemsControl}}">
                    <TextBlock.Margin>
                        <MultiBinding Converter="{StaticResource calcOffsetY}">
                            <Binding RelativeSource="{RelativeSource Self}"/>
                            <Binding Path="ActualWidth" RelativeSource="{RelativeSource AncestorType=ItemsControl}"/>
                        </MultiBinding>
                    </TextBlock.Margin>
                </TextBlock>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

我想你需要为此编写自己的包装面板。我的WPF已经生锈了,但我会说:用画布替换ItemsControl面板,然后将项目绑定到画布。顶部依赖属性哦,我错过了不重叠要求。我的解决方案不起作用,然后我会尝试使用自定义StackPanel和一个附加属性,如MyCustomStackPanel.MinY。这看起来很有希望-我会让你知道我的进展。。。谢谢你的帮助。我不明白你为什么加上:。。。这是为什么?另外,当Y更改时,这会自动移动我的项目吗?@LeonardoSeccia实际宽度绑定将在每次更改ItemsControl的宽度时(包括第一次进行初始化时)导致重新计算。如果你想让这个响应改变Y的值,你需要在MultiBinding中再添加一个绑定。我已经尝试过了,但它似乎不太正确。项目重叠和定位不太正确。当Y=0时,项目不在顶部-@LeonardoSeccia,因为你没有提到项目顺序,我只是简单地假设它们是按Y排序的。实际上,我的答案是利用WPF的布局计算来解决重叠问题的。因此,我建议您使用CollectionViewSource代替集合作为绑定源,并向CollectionViewSource添加SortDescription,使视图自动按Y排序。
public class CalcOffsetY : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var tbk = (TextBlock)values[0];
        var offsetY = tbk.TranslatePoint(tbk.RenderTransformOrigin, (UIElement)tbk.Tag).Y -
            tbk.Margin.Top;
        var y = ((YourModelType)tbk.DataContext).Y;

        tbk.SetCurrentValue(TextBlock.MarginProperty, new Thickness(tbk.Margin.Left, y > offsetY ? y - offsetY : 0,
            tbk.Margin.Right, tbk.Margin.Bottom));
        tbk.UpdateLayout(); // Update layout immediately, so next item will get correct result.

        return Binding.DoNothing; // Already nothing to do.
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}