私はこれを持っています:
<TabControl Margin="0,24,0,0">...</TabControl>
TabControlの"Top"
部分のみをバインドしたいのですが、直観的には次のようにします。
<TabControl Margin="0,{Binding ElementName=TheMenu, Path=Height},0,0">
...
</TabControl>
どうすればいいのですか ?
このようなコンバーターを使用してみましたか?
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>
編集:
MultiConverterの使用
実行時に4つの値すべてを取得し、MultiValueConverterを使用することもできます。 Thickness-ObjectのTop-PropertyはDependency-Objectではないため、バインディングを定義することはできません(ソースが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>
...および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:
これがあなたを幸せにするかどうかはわかりません。私の謙虚な意見では、私はこれを避けようとしますが、OK ...あなたのソースが依存関係プロパティである場合、これをマージンにバインドできます:
<Slider Name="Slider5" Minimum="-99" Maximum="0" Value="{Binding ElementName=TabControl, Path=Margin.Top, Mode=OneWayToSource}"></Slider>
しかし、これにはいくつかの効果があります。
トリックは、TabControlのMarginの一部を「他の何か」にバインドせず、TabControlのMarginに「他の何か」をバインドし、Binding-ModeOneWayToSource。
実際、コントロールのMargin
プロパティはThickness
タイプです。そのため、Thickness型の場合、プロパティにバインドできます。
public Thickness LeftMargin { get; set; }
また、Thicknessオブジェクトの一部も設定できます。お気に入り -
LeftMargin = new Thickness(20,0,0,0);
Xaml
では、このプロパティを任意の要素のmarginプロパティに直接バインドできます。
<TextBlock Text="Some Text" Margin="{Binding LeftMargin}" />
this 別の質問からの回答のようなものを試すことができます。
ソリューションでは、次のようなXAMLを許可する添付プロパティを使用します。
<Button ap:MoreProps.MarginRight="10" />
添付プロパティもDependencyObjectによってサポートされているため、データバインディングが機能します。
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>
あなたのコードから、私はあなたのメニューとtabControlが重複するかもしれないので、それらを分離するためにマージンを使いたいと思っています。このプラクティスは2列のCSSレイアウトのように感じます。
ポイントに戻ると、TranslateFransform
をTabControl.RenderTransform
に適用できると思います。 Y
プロパティをバインドできます。
別のWPF要素にアタッチしていない場合、コンバーターではなくマージンを制御するプロパティを作成する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
次に、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
は他のコントロールに再利用できます。