programing

WPF 컨트롤의 여백 속성의 일부만 바인딩

yellowcard 2023. 5. 15. 21:26
반응형

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컨트롤의 속성은 입니다.ThicknessType. 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

반응형