Binding Only Part Of The Margin Property Of WPF Control


Answer :

Have you tried using a converter like this?

in VB.Net

Public Class MarginConverter   Implements IValueConverter    Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert     Return New Thickness(0, CDbl(value), 0, 0)   End Function    Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack     Return Nothing   End Function End Class 

Or in C#

public class MarginConverter : IValueConverter {      public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)     {         return new Thickness(0, System.Convert.ToDouble(value), 0, 0);     }      public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)     {         return null;     } } 

XAML

<Window.Resources>     <local:MarginConverter x:Key="marginConverter"></local:MarginConverter> </Window.Resources> <Grid>     <StackPanel>         <Slider Name="Slider1"></Slider>         <TabControl Name="TabControl" Margin="{Binding ElementName=Slider1, Path=Value, Converter={StaticResource marginConverter}}">             <Button>Some content</Button>         </TabControl>     </StackPanel> </Grid> 

Edit:
Using a MultiConverter

It is also possible to get all four values during run-time and use a MultiValueConverter. The Top-Property of the Thickness-Object is not a Dependency-Object, therefor you can't define a binding to it (unless your source is not a Dependency-Object).

XAML

<Window.Resources>     <local:MarginConverter x:Key="marginConverter"></local:MarginConverter>     <local:MultiMarginConverter x:Key="multiMarginConverter"></local:MultiMarginConverter> </Window.Resources> <Grid>     <StackPanel>         <Slider Name="Slider1"></Slider>         <Slider Name="Slider2"></Slider>         <Slider Name="Slider3"></Slider>         <Slider Name="Slider4"></Slider>         <TabControl Name="TabControl">             <TabControl.Margin>                 <MultiBinding Converter="{StaticResource multiMarginConverter}">                     <Binding ElementName="Slider1" Path="Value"></Binding>                     <Binding ElementName="Slider2" Path="Value"></Binding>                     <Binding ElementName="Slider3" Path="Value"></Binding>                     <Binding ElementName="Slider4" Path="Value"></Binding>                 </MultiBinding>             </TabControl.Margin>             <Button>Some content</Button>         </TabControl>     </StackPanel> </Grid> 

... and c#

  class MultiMarginConverter : IMultiValueConverter   {     public object Convert(object[] values, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)     {       return new Thickness(System.Convert.ToDouble(values[0]),                            System.Convert.ToDouble(values[1]),                            System.Convert.ToDouble(values[2]),                            System.Convert.ToDouble(values[3]));     }      public object[] ConvertBack(object value, System.Type[] targetType, object parameter, System.Globalization.CultureInfo culture)     {       return null;     }   } 

Edit(2) Reverse-Binding:
I'm not sure if this will make you happy. In my humble opinion I would try to avoid this, but ok... If your source is a Dependency-Property, you can bind this to the Margin:

<Slider Name="Slider5" Minimum="-99" Maximum="0" Value="{Binding ElementName=TabControl, Path=Margin.Top, Mode=OneWayToSource}"></Slider> 

But I've got some effects with this.
The trick is, that you do not bind a part of the Margin of your TabControl to "something else", but bind "something else" to the Margin of your TabControl and specify Binding-Mode OneWayToSource.


Actually Margin property of a control is of Thickness Type. So we can bind it to Property if type Thickness.

 public Thickness LeftMargin { get; set; } 

and You can set a part of a Thickness object too. Like -

 LeftMargin = new Thickness(20,0,0,0); 

and in Xaml we can bind this property directly to margin property of any element..like this..

 <TextBlock Text="Some Text"  Margin="{Binding LeftMargin}"  /> 

You could try something like this answer from another question.

The solution uses an attached property that allows for XAML like the following:

<Button ap:MoreProps.MarginRight="10" /> 

The attached property is also backed by a DependencyObject so data binding will work.


Comments

Popular posts from this blog

Are Regular VACUUM ANALYZE Still Recommended Under 9.1?

Can Feynman Diagrams Be Used To Represent Any Perturbation Theory?