Wpf 将子控件锚定到父控件

Wpf 将子控件锚定到父控件,wpf,xaml,Wpf,Xaml,我是WPF新手,我想设置子控件相对于父控件的边距,而不是树中的前一个子控件。我正在使用IValueConverter转换边距 <Grid Background="#668" Margin="1"> <StackPanel Grid.Row="1" Orientation="Horizontal"> <ItemsControl ItemsSource="{Binding KeyFrames}" >

我是WPF新手,我想设置子控件相对于父控件的边距,而不是树中的前一个子控件。我正在使用IValueConverter转换边距

<Grid Background="#668" Margin="1">
            <StackPanel Grid.Row="1" Orientation="Horizontal">
                <ItemsControl ItemsSource="{Binding KeyFrames}" >
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                        <Button Width="{Binding Path=ScaledLength}" HorizontalAlignment="Left"
                                      Margin="{Binding Path=ScaledStartOffset, Converter={StaticResource ClipLeftMarginConverter} }">
                        </Button>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Horizontal"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                </ItemsControl>
            </StackPanel>
        </Grid>

我想知道是否有一个不同的控制,我可以使用这样的按钮边距是相对于网格,而不是以前的按钮。或者,如果您注意到我可以对IValueConverter进行更改,以解决相同的问题,我也可以。

您已经将StackPanel指定为ItemsPanelTemplate。StackPanel的语义是,每个子级将从上一个子级旁边开始,并且边距将相对于该位置应用

如果将ItemsPanelTemplate更改为不练习相对定位的面板,则每个子级将从相同的位置开始,然后将相对于该位置应用边距。可能最简单的方法是使用画布作为ItemsPanelTemplate。然后每个项目将从(0,0)开始,您的边距将其偏移到所需的位置


有一个使用画布将项目定位在由处的项目数据确定的绝对位置的示例(向下滚动到步骤4)。该示例使用ItemContainerStyle而不是Margin进行定位,但是如果您更喜欢Margin,那么它应该很容易适应。

使用Canvas而不是StackPanel。这可能会解决你的问题。 正如伊托尔森所说,Canvas开始让孩子们保持在0,0。因此,无论您给元素留有多少边距,都是相对于画布的。而不是上一个元素

下面的代码可能会有所帮助

    public partial class MainWindow : Window
{
    public ObservableCollection<Person> Persons { get; set; }
    public MainWindow()
    {
        InitializeComponent();

        Persons = new ObservableCollection<Person>();
        Persons.Add(new Person("one", 100));
        Persons.Add(new Person("two", 200));
        Persons.Add(new Person("three", 300));
        Persons.Add(new Person("four", 400));

        DataContext = this;
    }
}

public class Person
{
    public String Name { get; set; }
    public Thickness Age { get; set; }

    public Person(string name, int age)
    {
        this.Name = name;
        this.Age = new Thickness(age, 0, 0, 0);
    }
}


<Grid Background="#668" Margin="1">
        <ItemsControl ItemsSource="{Binding Persons}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}" Margin="{Binding Age}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
</Grid>
公共部分类主窗口:窗口
{
公共可观察集合人员{get;set;}
公共主窗口()
{
初始化组件();
人员=新的可观察集合();
增加(新的人员(“一”,100));
增加(新的人(“两个”,200));
增加(新的人(“三”,300));
增加(新的人(“四”,400));
DataContext=this;
}
}
公共阶层人士
{
公共字符串名称{get;set;}
公共属性{get;set;}
公众人物(字符串名称,整数年龄)
{
this.Name=Name;
这个。年龄=新厚度(年龄,0,0,0);
}
}
    public partial class MainWindow : Window
{
    public ObservableCollection<Person> Persons { get; set; }
    public MainWindow()
    {
        InitializeComponent();

        Persons = new ObservableCollection<Person>();
        Persons.Add(new Person("one", 100));
        Persons.Add(new Person("two", 200));
        Persons.Add(new Person("three", 300));
        Persons.Add(new Person("four", 400));

        DataContext = this;
    }
}

public class Person
{
    public String Name { get; set; }
    public Thickness Age { get; set; }

    public Person(string name, int age)
    {
        this.Name = name;
        this.Age = new Thickness(age, 0, 0, 0);
    }
}


<Grid Background="#668" Margin="1">
        <ItemsControl ItemsSource="{Binding Persons}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}" Margin="{Binding Age}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
</Grid>