2010-10-13 132 views
1

我想使用4個文本框設置用戶控件邊框的邊框厚度,但是我無法使它工作。WPF:4個文本框和1個邊框之間的雙向綁定。邊距

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正確顯示厚度的左側部分,但編輯文本框不會導致邊界左側呈現方式發生變化。奇怪的是,我爲Thickness.Left在TextBox中設置的值仍然存在,所以看起來該值確實已設置,但渲染未更新。 在示例代碼中,更改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

對我來說,最簡單的解決方案被證明是隻聽TextBox的TextChanged事件,並更換了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的解決方案是更好的。