英文:
Binding a list of rectangles to a canvas in AvaloniaUI
问题
以下是您提供的代码的中文翻译:
我正在尝试将一个矩形的可观察集合绑定到一个具有画布作为项面板的项控件,但似乎没有办法将Canvas.Left和Canvas.Top属性绑定到矩形项上。我尝试通过添加类似于在WPF中的ItemsControl.ItemContainerStyle的方式来实现这一点,但在Avalonia中似乎不存在这个选项。
我进行了搜索,找到了这个链接:https://github.com/AvaloniaUI/Avalonia/discussions/10018
然而,我在Avalonia文档中找不到任何关于ItemContainerTheme的参考。
这是我目前的代码:
<ItemsControl Grid.Row="1" Items="{Binding Rectangles}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Canvas.Left" Value="{Binding Path=X}" />
            <Setter Property="Canvas.Top" Value="{Binding Path=Y}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Rectangle Fill="Red" Width="{Binding Width}" Height="{Binding Height}"></Rectangle>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
这是每个项的视图模型,项模板正在绑定到它:
public class RectangleViewModel : ViewModelBase
{
    private int _x = 0;
    public int X
    {
        get => _x;
        set => this.RaiseAndSetIfChanged(ref _x, value);
    }
    private int _y = 0;
    public int Y
    {
        get => _y;
        set => this.RaiseAndSetIfChanged(ref _y, value);
    }
    private int _width = 0;
    public int Width
    {
        get => _width;
        set => this.RaiseAndSetIfChanged(ref _width, value);
    }
    private int _height = 0;
    public int Height
    {
        get => _height;
        set => this.RaiseAndSetIfChanged(ref _height, value);
    }
}
这是我的Rectangles集合:
public ObservableCollection<RectangleViewModel> Rectangles { get; } = new ObservableCollection<RectangleViewModel>();
英文:
I am trying to bind an observable collection of rectangles to an items control with a canvas as the item panel, but there seems to be no way of binding the Canvas.Left and Canvas.Top properties to the Rectangle items. I attempted to do this by adding a ItemsControl.ItemContainerStyle like one would in WPF, but this doesn't seem to exist in Avalonia.
I searched and found this: https://github.com/AvaloniaUI/Avalonia/discussions/10018
However, I couldn't find any reference to ItemContainerTheme on the Avalonia documentation.
This is what I have currently:
<ItemsControl Grid.Row="1" Items="{Binding Rectangles}">
	<ItemsControl.ItemsPanel>
		<ItemsPanelTemplate>
			<Canvas/>
		</ItemsPanelTemplate>
	</ItemsControl.ItemsPanel>
	<ItemsControl.ItemContainerStyle>
		<Style TargetType="ContentPresenter">
			<Setter Property="Canvas.Left" Value="{Binding Path=X}" />
			<Setter Property="Canvas.Top" Value="{Binding Path=Y}" />
		</Style>
	</ItemsControl.ItemContainerStyle>
	<ItemsControl.ItemTemplate>
		<DataTemplate>
			<Rectangle Fill="Red" Width="{Binding Width}" Height="{Binding Height}"></Rectangle>
		</DataTemplate>
	</ItemsControl.ItemTemplate>
</ItemsControl>
This is the view model for each item that the items template is binding to:
public class RectangleViewModel : ViewModelBase
{
	private int _x = 0;
	public int X
	{
		get => _x;
		set => this.RaiseAndSetIfChanged(ref _x, value);
	}
	private int _y = 0;
	public int Y
	{
		get => _y;
		set => this.RaiseAndSetIfChanged(ref _y, value);
	}
	private int _width = 0;
	public int Width
	{
		get => _width;
		set => this.RaiseAndSetIfChanged(ref _width, value);
	}
	private int _height = 0;
	public int Height
	{
		get => _height;
		set => this.RaiseAndSetIfChanged(ref _height, value);
	}
}
And this is my Rectangles collection:
public ObservableCollection<RectangleViewModel> Rectangles { get; } = new();
答案1
得分: 0
已解决。我成功找到了一个相关的GitHub问题,链接在这里:https://github.com/AvaloniaUI/Avalonia/issues/2302,它使用了附加的 Styles 属性来添加 Canvas.Left 和 Canvas.Top 属性。
修复后的结果:
<ItemsControl Grid.Row="1" Items="{Binding Rectangles}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.Styles>
        <Style Selector="ItemsControl > ContentPresenter">
            <Setter Property="Canvas.Left" Value="{Binding X}"/>
            <Setter Property="Canvas.Top" Value="{Binding Y}"/>
        </Style>
    </ItemsControl.Styles>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Rectangle Stroke="#00FF00" StrokeThickness="2" Fill="Transparent" Width="{Binding Width}" Height="{Binding Height}"></Rectangle>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
英文:
Solved. I managed to find a somewhat related Github issue here https://github.com/AvaloniaUI/Avalonia/issues/2302 that uses the attached Styles attribute to add the Canvas.Left and Canvas.Top properties.
The fixed result:
<ItemsControl Grid.Row="1" Items="{Binding Rectangles}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.Styles>
        <Style Selector="ItemsControl > ContentPresenter">
            <Setter Property="Canvas.Left" Value="{Binding X}"/>
            <Setter Property="Canvas.Top" Value="{Binding Y}"/>
        </Style>
    </ItemsControl.Styles>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Rectangle Stroke="#00FF00" StrokeThickness="2" Fill="Transparent" Width="{Binding Width}" Height="{Binding Height}"></Rectangle>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论