2011-06-06 83 views
37

的保证金财产的一部分,我有这样的:绑定唯一WPF控件

<TabControl Margin="0,24,0,0">...</TabControl> 

我想只有TabControl的,它直观地我会做这样的"Top"部分绑定:

<TabControl Margin="0,{Binding ElementName=TheMenu, Path=Height},0,0"> 
... 
</TabControl> 

我该怎么做?

回答

44

你试过用这样的转换器吗?

在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 

或者在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> 

编辑:
使用多转换

也可以在运行时获得全部四个值,并使用一个MultiValueConverter。 厚度对象的顶层属性不是依赖项对象,因此您无法定义对它的绑定(除非您的源不是依赖对象)。

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> 

......和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; 
    } 
    } 

编辑(2)反向绑定:
我不知道这是否会令你快乐。在我的愚见我会尽量避免这种情况,但确定......如果你的来源是依赖属性,你可以绑定这个到保证金:

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

但我有这个有一定的影响。
诀窍是,您不要将TabControl的边缘的一部分绑定到“其他”,而是将“其他”绑定到TabControl的边距并指定绑定模式OneWayToSource

+2

但这种方式迫使我在代码中输入所有其他的数字,是不是有使用子标签的标记,就像一个办法:'' – Tar 2011-06-06 12:01:16

+0

有关MultiValueConverter的详细信息和建议,请参阅编辑。顶部(和底部和....)不依赖于属性。对于绑定,至少有一部分必须是依赖属性。 – Markus 2011-06-06 12:33:16

+0

好的,谢谢,你给了我一些代码想想... – Tar 2011-06-06 13:32:52

2

你可以尝试类似this从另一个问题的答案。

该解决方案使用附加属性,其允许XAML类似如下:

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

的附加属性也通过为DependencyObject支持这样的数据绑定将工作。

2

从你的代码中,我认为你的菜单和tabControl可能会重叠,所以你想用margin来分开它们。我觉得这种做法像两列CSS布局。

回到这一点,我认为你可以申请TranslateFransformTabControl.RenderTransform。你可以绑定Y属性。

18

其实Margin控件的属性是Thickness类型。所以我们可以将它绑定到Property,如果输入Thickness。

public Thickness LeftMargin { get; set; } 

您也可以设置厚度对象的一部分。像 -

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

Xaml我们可以将此属性直接绑定到任何element..like这个margin属性..

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

我认为如果你只有一边绑定,这是正确的方法。否则,如果您需要控件边距各边的不同值,则需要其他选项。 – heltonbiker 2016-01-18 19:49:46

+2

@heltonbiker我认为这很完美,你可以分别设置左,右,上,下各个值,并设置不同的值。 – CularBytes 2016-06-08 14:30:32

1

要在制作属性来控制利润率,而不是Ioop的方法扩大

创建4点标准的属性和只读属性,像所谓

Public Class CustomMargin 
    Implements INotifyPropertyChanged 

    Private _Left As Double 
    Private _Right As Double 
    Private _Up As Double 
    Private _Down As Double 

    Public Sub New() 
     _Up = 0 
     _Down = 0 
     _Left = 0 
     _Right = 0 
    End Sub 

    Public Sub New(Vertical as Double, Horizontal as Double) 
     _Up = Vertical 
     _Down = Vertical 
     _Left = Horizontal 
     _Right = Horizontal 
    End Sub 

    Public Sub New(Left as Double, Up as Double, Right as Double, Down as Double) 
     _Up = Up 
     _Down = Down 
     _Left = Left 
     _Right = Right 
    End Sub 

    Public Property Left As Double 
     Get 
      Return _Left 
     End Get 
     Set(value As Double) 
      _Left = value 
      OnPropertyChanged(New PropertyChangedEventArgs("MyMargin")) 
     End Set 
    End Property 

    Public Property Right As Double 
     Get 
      Return _Right 
     End Get 
     Set(value As Double) 
      _Right = value 
      OnPropertyChanged(New PropertyChangedEventArgs("MyMargin")) 
     End Set 
    End Property 

    Public Property Up As Double 
     Get 
      Return _Up 
     End Get 
     Set(value As Double) 
      _Up = value 
      OnPropertyChanged(New PropertyChangedEventArgs("MyMargin")) 
     End Set 
    End Property 

    Public Property Down As Double 
     Get 
      Return _Down 
     End Get 
     Set(value As Double) 
      _Down = value 
      OnPropertyChanged(New PropertyChangedEventArgs("MyMargin")) 
     End Set 
    End Property 

    Public ReadOnly Property MyMargin As Thickness 
     Get 
      Return New Thickness(Left, Up, Right, Down) 
     End Get 
    End Property 

    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged 

    Public Sub OnPropertyChanged(ByVal e As PropertyChangedEventArgs) 
     If Not PropertyChangedEvent Is Nothing Then 
      RaiseEvent PropertyChanged(Me, e) 
     End If 
    End Sub 
End Class 
:如果你没有连接到另一个WPF元素的转换器

然后你只需要添加XAML -

<Label x:Name="MyLabel" Margin="{Binding Path=MyMargin, FallbackValue=0 0 0 0, Mode=OneWay}"/> 

然后在后面的代码在WPF窗口 -

Private _NewMargin as New CustomMargin 

Public Sub New() 
    InitializeComponent() 
    MyLabel.DataContext = _NewMargin 
End Sub 

从那里,不管你控制什么希望改变所有4个边缘,你可以使用单独和Class可重复使用其他控件。

3

我已经使用这种解决方法仅用于StackPanel左边距。好处是你不需要任何转换器。

<DockPanel VerticalAlignment="Top"> 
    <TextBlock Name="tbkFulltextCaption" 
      Text="Static Caption:" 
      DockPanel.Dock="Left" /> 
    <StackPanel Orientation="Horizontal" 
       DockPanel.Dock="Bottom"> 
     <FrameworkElement Name="feLeftMargin" 
         Width="{Binding Width, ElementName=tbkFulltextCaption, Mode=OneWay}" /> 
     <TextBlock Text="(some text with margin of tbkFulltextCaption.Width)" 
       Name="tbkUnderNonsense" 
       FontSize="8"          
       Foreground="Gray"> 
     </TextBlock> 
    </StackPanel> 
    <TextBox Name="tbFulltextSearch" /> 
</DockPanel> 

preview