我是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是
public class ClipRegionMarginConverter : DependencyObject, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double inputValue = (double)value;
return new Thickness(inputValue, 0, 0, 0);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new Exception("The method or operation is not implemented.");
}
}
我想知道我是否可以使用不同的控件,以便按钮边距相对于网格而不是前一个按钮。或者,如果您注意到我可以对IValueConverter进行更改以解决同样的问题,我也可以使用它。
答案 0 :(得分:2)
您已将StackPanel指定为ItemsPanelTemplate。 StackPanel具有每个孩子将从前一个孩子旁边开始的语义,并且相对于该位置将应用边距。
如果将ItemsPanelTemplate更改为不练习相对定位的面板,则每个子项将从相同位置开始,然后将相对于该位置应用边距。可能最简单的方法是使用Canvas作为ItemsPanelTemplate。然后每个项目将从(0,0)开始,您的保证金将其偏移到所需的位置。
有一个使用Canvas将项目定位在由http://www.mindscapehq.com/blog/index.php/2007/12/04/five-steps-to-wpf-data-visualisation/的项目数据确定的绝对位置的示例(向下滚动到步骤4)。该示例使用ItemContainerStyle而不是Margin进行定位,但如果您更喜欢Margin,那么它应该很容易适应。
答案 1 :(得分:0)
使用Canvas而不是使用StackPanel。这可能会解决您的问题。 正如itowlson所说,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>