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.xorMargin.Xor ..., but that seems not to work. - I tried replacing
MarginwithLeftbut 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 )
