2016-09-20 62 views

回答

0

我们当然可以采用非常简单的方式使用代码更改Margin

对于纯粹的MVVM方法,您可以使用AttachedProperty来实现。为Thickness类型不是DependencyObject

BindingConvertor不会在这里工作。

如果我们只是绑定的外ButtonMargin到内Button,外Button整个Margin会发生变化,这是我们不希望。所以,我们需要保留整个Margin,除了Left MarginLeft Margin可以使用Binding进行更改。但是如何?我们的外部Button需要有两个Margin值,一个原始值,另一个来自inner Button,以便可以更改原始值。对于另一个保证金,我们可以帮助Attached Property,因为它们允许我们扩展控制权。

AttachedProperty

public static BindingExpression GetLefMargin(DependencyObject obj) 
{ 
    return (BindingExpression)obj.GetValue(LefMarginProperty); 
} 

public static void SetLefMargin(DependencyObject obj, BindingExpression value) 
{ 
    obj.SetValue(LefMarginProperty, value); 
} 

// Using a DependencyProperty as the backing store for LefMargin. This enables animation, styling, binding, etc... 
public static readonly DependencyProperty LefMarginProperty = 
    DependencyProperty.RegisterAttached("LefMargin", typeof(BindingExpression), typeof(Window1), new PropertyMetadata(null, new PropertyChangedCallback(MarginCallback))); 

private static void MarginCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    FrameworkElement elem = d as FrameworkElement; 
    BindingExpression exp = e.NewValue as BindingExpression;    

    // Create a new Binding to set ConverterParameter // 

    Binding b = new Binding(); 
    b.Converter = exp.ParentBinding.Converter; 
    b.ConverterParameter = elem.Margin; 
    b.Path = exp.ParentBinding.Path; 
    b.ElementName = exp.ParentBinding.ElementName; 
    b.Mode = exp.ParentBinding.Mode; 

    elem.SetBinding(FrameworkElement.MarginProperty, b); 
} 

转换

public class LeftMarginCnv : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     double gridCtrlLeftMargin = ((Thickness)value).Left; 
     Thickness tgtCtrlMargin = (Thickness)parameter; 

     return new Thickness(gridCtrlLeftMargin, tgtCtrlMargin.Top, tgtCtrlMargin.Right, tgtCtrlMargin.Bottom); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

用法

<Grid> 
    <Grid Background="Red" Margin="29,55,52,125" ShowGridLines="True"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="90*"/> 
      <ColumnDefinition Width="121*"/> 
     </Grid.ColumnDefinitions> 
     <Button x:Name="Btn" Content="Press" Margin="18,22,35,28" Grid.Column="1" Click="Btn_Click"/>    
    </Grid> 
    <Button local:Window1.LefMargin="{Binding Margin, ElementName=Btn, Converter={StaticResource LeftMarginCnvKey}}" Content="Button" HorizontalAlignment="Left" Margin="55,199,0,0" VerticalAlignment="Top" Width="75"/> 
</Grid> 

外如果更改内部Button的左边距,则将更改其Left Margin

+0

你能解释一些更多的信息 –

+0

@ShobhaM Plz检查更新的答案,并逐一提出疑问。 – AnjumSKhan

0

您可以为两者设置通用样式。像这样的东西。

<StackPanel> 
    <StackPanel.Resources> 
     <Style x:Key="commonstyle" TargetType="{x:Type FrameworkElement}"> 
      <Setter Property="Margin" Value="10,0,0,0" /> 
     </Style> 
    </StackPanel.Resources> 
    <TextBox x:Name="outside" Width="100" Height="70" Style="{StaticResource commonstyle}"/> 
    <Grid ShowGridLines="True"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="*" /> 
     </Grid.ColumnDefinitions> 
     <Button Width="100" Height="70" x:Name="inside" Grid.Column="2" HorizontalAlignment="Left" Style="{StaticResource commonstyle}"/> 
    </Grid> 
</StackPanel> 

(或)

使简单

<StackPanel> 
    <TextBox x:Name="outside" Width="100" Height="70" Margin="{Binding ElementName=inside, Path=Margin}"/> 
    <Grid ShowGridLines="True"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="*" /> 
     </Grid.ColumnDefinitions> 
     <Button Width="100" Height="70" x:Name="inside" Grid.Column="2" HorizontalAlignment="Left" Margin="20"/> 
    </Grid> 
</StackPanel> 

希望有所帮助。