2010-10-13 2 views
1

Я хочу установить BorderThickness границы UserControl, используя 4 TextBoxes, но я не могу заставить его работать.WPF: привязка TwoWay между 4 TextBoxes и 1 Border.Margin

XAML-код, демонстрирующий проблему (только этот код в сочетании с необходима преобразователь):

<Window 
    x:Class="BorderThicknessBindingTest.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:BorderThicknessBindingTest="clr-namespace:BorderThicknessBindingTest" 
    Height="300" Width="500"> 
    <Window.Resources> 
     <BorderThicknessBindingTest:ThicknessConverter x:Key="ThicknessConverter"/> 
    </Window.Resources> 

    <Grid Margin="10"> 
     <Border 
      x:Name="MyBorder" 
      BorderBrush="Black" 
      Background="AliceBlue" 
      BorderThickness="3"/> 
     <TextBox 
      HorizontalAlignment="Center" VerticalAlignment="Center" 
      Text="{Binding Path=BorderThickness.Left, ElementName=MyBorder, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource ThicknessConverter}}"/> 
    </Grid> 
</Window> 

преобразователь необходим для разбора входной строки в TextBox:

public class ThicknessConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return value; // don't need to do anything here 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     double d; 
     Double.TryParse((string) value, out d); // Thickness.Left doesn't take a string 
     return d; 
    } 
} 

TextBox правильно отображает левую часть толщины, но редактирование TextBox не приводит к изменению способа отображения левой стороны границы. Как ни странно, значение, которое я установил в TextBox для Thickness.Left, сохраняется, поэтому кажется, что значение действительно установлено, но рендеринг не обновляется. В примере кода, изменяя значение в TextBox, а затем изменяя размер окна, показано, что граница слева занимает дополнительное пространство, но это пробел пуст.

Кто-нибудь знает, как это сделать и как это сделать?

ответ

2

Это не динамически обновляет элемент на экране, потому что ничего не сказал элемент, что поле в свойстве BorderThickness изменилось. Вам необходимо уведомить элемент, который его BorderThickness изменил, что вы можете сделать, просто установив для свойства зависимостей новое значение - скажем, сделав его объектом привязки к объекту, который меняет уведомление.

Это что-то больное, чтобы сделать модель для этого, но как только вы это сделаете.

окно:

<Window x:Class="ThicknessDemo.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ComponentModel="clr-namespace:System.ComponentModel;assembly=System" xmlns:ThicknessDemo="clr-namespace:ThicknessDemo" Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <ThicknessDemo:ThicknessViewModel x:Key="thickness" /> 
    </Window.Resources> 
     <DockPanel DataContext="{StaticResource thickness}"> 
      <Border DockPanel.Dock="Top" 
        Width="100" 
        Height="50" 
        Margin="5" 
        BorderBrush="Blue" 
        BorderThickness="{Binding Thickness}" /> 
      <TextBox DockPanel.Dock="Top" 
         Text="{Binding Left, Mode=TwoWay}" /> 
      <TextBox DockPanel.Dock="Top" 
         Text="{Binding Right, Mode=TwoWay}" /> 
      <TextBox DockPanel.Dock="Top" 
         Text="{Binding Top, Mode=TwoWay}" /> 
      <TextBox DockPanel.Dock="Top" 
         Text="{Binding Bottom, Mode=TwoWay}" /> 
      <TextBlock DockPanel.Dock="Top" /> 
     </DockPanel> 
</Window> 

Вид модели:

public class ThicknessViewModel : INotifyPropertyChanged 
{ 
    private void OnPropertyChanged(string propertyName) 
    { 
     PropertyChangedEventHandler h = PropertyChanged; 
     if (h != null) 
     { 
      h(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public ThicknessViewModel() 
    { 
     _Thickness = new Thickness(1, 1, 1, 1); 
    } 

    private Thickness _Thickness; 

    public Thickness Thickness { get { return _Thickness; } set { _Thickness = value;} } 

    public double Left 
    { 
     get { return _Thickness.Left; } 
     set 
     { 
      _Thickness.Left = value; 
      OnPropertyChanged("Thickness"); 
     } 
    } 

    public double Right 
    { 
     get { return _Thickness.Right; } 
     set 
     { 
      _Thickness.Right = value; 
      OnPropertyChanged("Thickness"); 
     } 
    } 

    public double Top 
    { 
     get { return _Thickness.Top; } 
     set 
     { 
      _Thickness.Top = value; 
      OnPropertyChanged("Thickness"); 
     } 
    } 

    public double Bottom 
    { 
     get { return _Thickness.Bottom; } 
     set 
     { 
      _Thickness.Bottom = value; 
      OnPropertyChanged("Thickness"); 
     } 
    } 
} 
0

Самое простое решение для меня оказывается просто слушать событие TextChanged в TextBox, и заменить BorderThickness в код позади.

MainWindow.xaml:

<Window 
    x:Class="BorderThicknessBindingTest.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:BorderThicknessBindingTest="clr-namespace:BorderThicknessBindingTest" 
    Height="300" Width="500"> 

    <Grid Margin="10"> 
     <Border 
      x:Name="MyBorder" 
      BorderBrush="Black" 
      Background="AliceBlue" 
      BorderThickness="3"/> 
     <TextBox 
      x:Name="MyTextBox" 
      HorizontalAlignment="Center" VerticalAlignment="Center" 
      Text="{Binding Path=BorderThickness.Left, ElementName=MyBorder, Mode=OneWay}"/> 
    </Grid> 
</Window> 

MainWindow.xaml.cs, в конструкторе:

MyTextBox.TextChanged += (sender, e) => 
{ 
    double d; 
    if (!double.TryParse(MyTextBox.Text, out d)) return; 
    var t = MyBorder.BorderThickness; 
    t.Left = d; 
    MyBorder.BorderThickness = t; 
}; 

Прямо сейчас это работает для меня, решение Роберта Rossney является лучше.

Смежные вопросы