Reputation: 27575
I have an ObservableCollection<Point>
that is displayed with an ItemsControl
, where I set the ItemsPanelTemplate
, ItemsPanel
and ItemTemplate
properties in XAML.
I want my points to represent normalized positions inside a bounding box. So, if I have a Point(0.5, 0.5)
, it will be in the exact middle of the container. Now if it is Point(0.25, 0.75)
, it will be positioned at 25% of the container width, and 75% of the container height.
The question is: how I make it happen in WPF? Should I put a ValueConverter in the ItemContainerStyle Bindings? Should I use a Behavior, a DataTemplate, an ElementBinding, a MultiBinding...?
I'm a bit lost...
XAML code, working with absolute positioning (not what I want):
<ItemsControl x:Name="MarcadoresSelecionadosZoom" ItemsSource="{Binding ListaPontos}" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="{x:Null}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="{x:Type FrameworkElement}">
<Setter Property="Canvas.Left" Value="{Binding X}" />
<Setter Property="Canvas.Top" Value="{Binding Y}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="Point">
<Ellipse Fill="Blue"
Width="8"
Height="8"
Margin="-4,-4,4,4" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Upvotes: 0
Views: 713
Reputation: 27575
Well, I got it working with a relatively simple (although verbose as always with XAML) solution involving MultiBinding and MultiValueConverter. I changed the ItemContainerStyle
alone, and created the Converter in codebehind:
XAML:
<ItemsControl.ItemContainerStyle>
<Style TargetType="{x:Type FrameworkElement}">
<Setter Property="Canvas.Left">
<Setter.Value>
<MultiBinding Converter="{StaticResource NormalConverter}">
<Binding Path="X"/>
<Binding ElementName="MarcadoresSelecionados" Path="ActualWidth"/>
</MultiBinding>
</Setter.Value>
</Setter>
<Setter Property="Canvas.Top">
<Setter.Value>
<MultiBinding Converter="{StaticResource NormalConverter}">
<Binding Path="Y"/>
<Binding ElementName="MarcadoresSelecionados" Path="ActualHeight"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</ItemsControl.ItemContainerStyle>
Converter:
public class NormalConverter : IMultiValueConverter
{
public object Convert(object[] values,
System.Type targetType,
object parameter,
System.Globalization.CultureInfo culture)
{
double menor = (double)values[0];
double maior = (double)values[1];
return maior * menor;
}
public object[] ConvertBack(object value, System.Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new System.NotImplementedException();
}
}
Upvotes: 1