WPF 컨트롤의 여백 속성의 일부만 바인딩
나는 다음을 가지고 있습니다.
<TabControl Margin="0,24,0,0">...</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>
편집:
다중 변환기 사용
런타임 중에 네 가지 값을 모두 가져오고 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;
}
}
편집(2) 역방향 바인딩:
이것이 당신을 행복하게 할지 모르겠어요.제 겸손한 의견으로는, 저는 이것을 피하려고 노력할 것입니다, 하지만 좋아요...원본이 종속성-속성인 경우 이를 여백에 바인딩할 수 있습니다.
<Slider Name="Slider5" Minimum="-99" Maximum="0" Value="{Binding ElementName=TabControl, Path=Margin.Top, Mode=OneWayToSource}"></Slider>
하지만 저는 이것으로 약간의 효과를 얻었습니다.
TabControl 여백의 일부를 "다른 것"에 바인딩하지 않고 "다른 것"을 TabControl 여백에 바인딩하고 Binding-Mode OneWayToSource를 지정하는 것이 중요합니다.
정말로.Margin
컨트롤의 속성은 입니다.Thickness
Type. Thickness를 입력하면 Property로 바인딩할 수 있습니다.
public Thickness LeftMargin { get; set; }
또한 Thickness 개체의 일부를 설정할 수도 있습니다.예를 들어 -
LeftMargin = new Thickness(20,0,0,0);
그리고.Xaml
우리는 이 속성을 어떤 요소의 마진 속성에 직접 결합할 수 있습니다.이렇게..
<TextBlock Text="Some Text" Margin="{Binding LeftMargin}" />
당신은 다른 질문에서 이와 같은 대답을 시도할 수 있습니다.
이 솔루션은 다음과 같이 XAML을 허용하는 연결된 속성을 사용합니다.
<Button ap:MoreProps.MarginRight="10" />
연결된 속성도 종속성 개체에 의해 지원되므로 데이터 바인딩이 작동합니다.
이 해결 방법은 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>
코드에서 메뉴와 탭 컨트롤이 중복될 수 있으므로 여백을 사용하여 구분하고자 합니다.저는 이 연습이 두 개의 칼럼 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
다른 컨트롤에 재사용할 수 있습니다.
네, 오래됐지만 더 좋은 방법을 찾고 있었어요.
<TabControl>
<TabControl.Margin>
<Thickness Top="{Binding ElementName=TheMenu, Path=Height}" />
</TabControl.Margin>
</TabControl>
언급URL : https://stackoverflow.com/questions/6249518/binding-only-part-of-the-margin-property-of-wpf-control
'programing' 카테고리의 다른 글
심층 복제 개체 (0) | 2023.05.15 |
---|---|
Postgresql에 제목이 있는 CSV로 테이블을 내보내는 방법은 무엇입니까? (0) | 2023.05.15 |
다른 테이블의 필드에서 한 테이블의 SQL 업데이트 필드 (0) | 2023.05.15 |
Python의 함수 체인 (0) | 2023.05.15 |
특정 화이트리스트를 제외한 모든 HTML 태그를 필터링하려면 어떻게 해야 합니까? (0) | 2023.05.15 |