I'm taking my first steps in WPF binding, and I would like to bind two visual components: a DataGrid
and a Label
, the latter to be put above the other (not in front of it, I mean).
This is what I currently have:
<DataGrid x:Name="dg_SomeTable" HorizontalAlignment="Left" Height="auto"
Margin="10,26,0,0" VerticalAlignment="Stretch" Width="74"/>
<Label Content="SomeTable" HorizontalAlignment="Left" Margin="10,0,0,0"
VerticalAlignment="Top"
Width="{Binding Path=ActualWidth, ElementName=dg_SomeTable}"/>
As you can see, the Label
's width is bounded to the width of the DataGrid
.
This is already useful, but I'd like to go a step further, and not only bind the width, but also the X-coordinate.
I believe that that X-coordinate is the first entry of the Margin
property, but I can't simply bind to that whole property, because this would place my Label
in front of my DataGrid
.
I have already done some very naïve steps:
- I tried working with
Margin.x
orMargin.X
or ..., but that seems not to work. - I tried replacing
Margin
withLeft
but that seems not to exist and I'm out of inspiration.
Does anybody know the good way to bind the X-coordinate of one visual component to the X-coordinate of another visual component, when the definition of the X-coordinates are embedded in the Margin
property?
Oh, I checked this similar question but this involves actual programming, and I'm wondering if there's a simple XAML solution for this seemingly basic question.
Edit after comment, asking for more information:
Generally my XAML looks as follows:
<TabControl ...
<TabItem ...
<Grid ...
<DataGrid x:Name="dg_SomeTable" ... Margin=... />
<Label Content="SomeTable" ... />
As proposed, this should be replaced by something like:
<TabControl ...
<TabItem ...
<Canvas ...
<DataGrid x:Name="dg_SomeTable" Width="222" Canvas.Left="10" ...
<Label Content="SomeTable"
Canvas.Left="{Binding Path=Left,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Canvas}}}"
Width="{Binding Path=ActualWidth,
ElementName=dg_Locations}"/>
I can already hear your reaction "Now you are referring to the left of the Canvas
where it's located in, while you should refer to the Canvas.Left
of the DataGrid
".
Well, I tried these:
Canvas.Left="{Binding Path=Canvas.Left, ElementName=dg_SomeTable}"
Canvas.Left="{Binding Path=Left, ElementName=dg_SomeTable}"
None of them worked.
How can I refer to the Canvas.Left
of the DataGrid
?
CodePudding user response:
How can I refer to the Canvas.Left of the DataGrid?
Like this (note the parentheses around the attached property name):
Canvas.Left="{Binding Path=(Canvas.Left), ElementName=dg_SomeTable}"
CodePudding user response:
Use converter
Step1. Make Converter
public class MarginConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (!(value is Thickness)) return new Thickness(0, 0, 0, 0);
Thickness gridMargin = (Thickness)value;
return new Thickness(gridMargin.Left, 0,0,0);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return parameter;
}
}
Step2. Add to resource
<Window.Resources>
<local:MarginConverter x:Key="MarginConverter"/>
</Window.Resources>
Step3. Bind Margin with converter
<Label Content="SomeTable" HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="{Binding Path=ActualWidth, ElementName=dg_SomeTable}"
Margin="{Binding Margin, ElementName=dg_SomeTable, Converter= {StaticResource MarginConverter}}"/>
This converter get dg_SomeTable's Margin and return new Margin ( dg_table's Margin.Left, 0 , 0, 0 )