英文:
"Canvas" methods doesn't work in itemsControl
问题
Canvas 方法通常在 canvas 标签中使用时可以正常工作,但当您尝试在 ItemsControl 中使用它们时,有时会停止工作。以下是一个示例:
<ItemsControl>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button Click="Button_Click">Text</Button>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
xaml.cs 文件:
private void Button_Click(object sender, RoutedEventArgs e)
{
    MessageBox.Show(Canvas.GetTop(sender as Button).ToString());
}
在这里,消息框返回 NaN,我不知道原因。您也不能使用 SetTop 或 left 方法。您能帮忙吗?
编辑: 这里有另一件有趣的事情
如果我给元素命名,它确实可以工作,但我不想这样做,因为名称在 itemTemplate 中不可用。
以下是代码:
<ItemsControl ItemsSource="{Binding SomeList}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <Button x:Name="Btn" Click="Button_Click">Text</Button>
</ItemsControl>
xaml.cs 文件:
private void Button_Click(object sender, RoutedEventArgs e)
{
    MessageBox.Show(Canvas.GetTop(Btn).ToString());
}
英文:
Canvas methods always work when they are in a canvas tag, but When you tryna use them in an itemsControl, they sometimes stop working. here's an example:
<ItemsControl>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button Click="Button_Click">Text</Button>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
   
    </ItemsControl>
xaml.cs file
private void Button_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show(Canvas.GetTop(sender as Button).ToString());
    }
Here messagebox returns Nan and I don't know the reason. You can't use SetTop or left method either. Can you help?
Edit: Here's another interesting thing
if I give a name to an element it does work, but I don't want that because the names aren't available in the itemTemplate.
here's the code:
 <ItemsControl ItemsSource="{Binding SomeList}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
   <Button x:Name="Btn" Click="Button_Click">Text</Button>
   
    </ItemsControl>
xaml.cs file
 private void Button_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show(Canvas.GetTop(Btn).ToString());
    }
答案1
得分: 1
为了定义ItemTemplate中元素的绝对位置,您应该将容器的Canvas.Top附加属性绑定到SomeList集合中对象类型的属性:
<ItemsControl ItemsSource="{Binding SomeList}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Canvas.Top" Value="{Binding Top}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button Click="Button_Click">Text</Button>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
SomeList应该是一个IEnumerable<T>,其中类型T具有double类型的Top属性:
public class Item
{
    public double Top { get; set; }
}
英文:
To position define the absolute position of the element in the ItemTemplate,  you should bind the Canvas.Top attached property of the container to a property of the type of objects in the SomeList collection:
<ItemsControl ItemsSource="{Binding SomeList}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Canvas.Top" Value="{Binding Top}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button Click="Button_Click">Text</Button>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
SomeList should be an IEnumerable<T> where the type T has a Top property of type double:
public class Item
{
    public double Top { get; set; }
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论