MultiBinding
의 하위 바인딩 업데이트를 건너 뛰는 방법은 무엇입니까? 나는 코드 숨김으로 정의했다. (나는 XAML에서 문제를 일으켰다. 문제가 없다고 생각한다. 모든 코드 숨김이 XAML보다 덜 표현한 후에) 두 개의 읽기 전용 속성과 하나의 일반 속성을 갖는 MultiBinding
단일 값을 생성합니다. ConvertBack
의 경우 읽기 전용 속성은 수정되지 않고 (값을 유지함) 일반 속성 만 변경됩니다.읽기 전용 속성이있는 TwoWay MultiBinding
TwoWay
에 전체가 MultiBinding
MultiBinding
설정된 상태를 정의하지만 적절한 (처음 두 OneWay
과 두 번째로 TwoWay
) 특정 서브 세트의 바인딩.
문제가 자체 제어에서 발생합니다. 그러나 프리젠 테이션을 위해서 나는 그것을 더 작은 컨트롤로 단순화했다. 이 예제에서 제시된 컨트롤은 Slider
과 같은 컨트롤로 [0.0; 1.0] 범위. 선택한 값은 엄지 손가락으로 표시되고 DependencyProperty
으로 표시됩니다.
기본적으로 컨트롤은 1 행 x 3 열 Grid
에 의해 빌드되며 엄지 손가락은 가운데 열에 있습니다. 엄지 손가락을 정확하게 위치 시키려면 왼쪽 열에 선택한 위치에 해당하는 너비를 지정해야합니다. 그러나이 너비는 전체 컨트롤의 실제 너비와 엄지 자체의 실제 너비에 따라 달라집니다 (위치가 [0.0; 1.0] 범위의 상대 값으로 주어지기 때문입니다).
엄지 손가락을 움직일 때 위치는 적절히 업데이트되어야하지만 엄지 손가락 폭과 조절 폭은 분명히 변경되지 않습니다.
엄지 손가락 이동 중에 IDE에서 실행될 때 코드가 예상대로 작동합니다. MultiBinding
이 값을 두 개의 읽기 전용 속성으로 설정하려고 시도 할 때보고되는 예외 정보로 출력 창이 복잡해집니다. 나는 그것이 해롭지는 않다고 생각하지만 그것은 다소 귀찮고 오해의 소지가있다. 또한 코드가 다른 것을 수행한다는 것을 의미합니다. 그런 다음 해당 속성을 설정하지 않으려 고 했으므로 (실제로는 읽기 전용이 아니며 실제로 수정 될 수 있습니다.)
MultiBinding
documentation 비고 섹션에서 개별 하위 바인딩이 MultiBinding
모드 값을 무시할 수는 있지만 작동하지 않는다는 것을 언급합니다.
컨트롤과 엄지 너비 (읽기 전용 속성)에 대한 의존성을 어떻게 든 다르게 표현하면 어쩌면 해결 될 수 있습니다. 예를 들어 개별적으로 알림에 등록하고 변경시 업데이트를 적용하는 경우. 그러나 그것은 내게 자연스럽지 않습니다. MultiBinding
은 왼쪽 열 너비가이 세 가지 속성에 따라 달라 지므로 다른 한편으로 마찬가지입니다.
다음은 XAML 코드 예입니다. 여기
<UserControl x:Class="WpfTest.ExampleUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="leftColumn" />
<ColumnDefinition x:Name="thumbColumn" Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!-- Rectangle used in the left column for better visualization. -->
<Rectangle Grid.Column="0">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Color="Black" Offset="0" />
<GradientStop Color="White" Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<!-- Thumb representing the Position property. -->
<GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Center" />
<!-- Rectangle used in the right column for better visualization. -->
<Rectangle Grid.Column="2">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Color="White" Offset="0" />
<GradientStop Color="Black" Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Grid>
</UserControl>
그리고
은 MultiBinding 잘 작동하지 않는 것처럼using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace WpfTest
{
public partial class ExampleUserControl : UserControl
{
#region PositionConverter
private class PositionConverter : IMultiValueConverter
{
public PositionConverter(ExampleUserControl owner)
{
this.owner = owner;
}
#region IMultiValueConverter Members
public object Convert(
object[] values,
Type targetType,
object parameter,
CultureInfo culture)
{
double thisActualWidth = (double)values[0];
double thumbActualWidth = (double)values[1];
double position = (double)values[2];
double availableWidth = thisActualWidth - thumbActualWidth;
double leftColumnWidth = availableWidth * position;
return new GridLength(leftColumnWidth);
}
public object[] ConvertBack(
object value,
Type[] targetTypes,
object parameter,
CultureInfo culture)
{
double thisActualWidth = owner.ActualWidth;
double thumbActualWidth = owner.thumbColumn.ActualWidth;
GridLength leftColumnWidth = (GridLength)value;
double availableWidth = thisActualWidth - thumbActualWidth;
double position;
if (availableWidth == 0.0)
position = 0.0;
else
position = leftColumnWidth.Value/availableWidth;
return new object[] {
thisActualWidth, thumbActualWidth, position
};
}
#endregion
private readonly ExampleUserControl owner;
}
#endregion
public ExampleUserControl()
{
InitializeComponent();
MultiBinding leftColumnWidthBinding = new MultiBinding()
{
Bindings =
{
new Binding()
{
Source = this,
Path = new PropertyPath("ActualWidth"),
Mode = BindingMode.OneWay
},
new Binding()
{
Source = thumbColumn,
Path = new PropertyPath("ActualWidth"),
Mode = BindingMode.OneWay
},
new Binding()
{
Source = this,
Path = new PropertyPath("Position"),
Mode = BindingMode.TwoWay
}
},
Mode = BindingMode.TwoWay,
Converter = new PositionConverter(this)
};
leftColumn.SetBinding(
ColumnDefinition.WidthProperty, leftColumnWidthBinding);
}
public static readonly DependencyProperty PositionProperty =
DependencyProperty.Register(
"Position",
typeof(double),
typeof(ExampleUserControl),
new FrameworkPropertyMetadata(0.5)
);
public double Position
{
get
{
return (double)GetValue(PositionProperty);
}
set
{
SetValue(PositionProperty, value);
}
}
}
}
감사합니다. 이것은 내가 알 필요가있는 것이다! ConvertBack에서 해당 속성의 입력 값을 쉽게 얻을 수 있습니까? –
고마워요! 값을 다시 변환하기를 원하는 개별 '내부'바인딩을 언급하는 것이 가치가 있을지도 모르지만,'Mode = TwoWay'로 설정해야합니다. 설명서에서 찾지 못했습니다. : / –