2012-12-19 16 views
0

그래서 "ShowCode"속성을 사용하여 속성을 사용하는 방법을 배우는 userControl을 만들었습니다. 이 속성을 사용하여 표의 두 번째 행을 숨길 수 있습니다.바인딩이 작동하지 않는 이유는 무엇입니까?

보기 :이처럼 사용하는 경우 :

이 코드

<UserControl x:Class="Test.UserControl1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     mc:Ignorable="d" 
     d:DesignHeight="300" d:DesignWidth="300"> 
    <Grid Margin="0,0,0,0" Name="outergrid" DataContext="{Binding}"> 
     <Grid.RowDefinitions> 
     <RowDefinition Height="3*" /> 
     <RowDefinition Height="1*" /> 
    </Grid.RowDefinitions> 

    <ContentControl Name="XAMLView" Grid.Row="0"/> 
    <GridSplitter ResizeDirection="Rows" 
       Grid.Row="0" 
       VerticalAlignment="Bottom" 
       HorizontalAlignment="Stretch" /> 
    <Border Width="11" Grid.Row="1" Background="Black" /> 
</Grid> 
을 :

public partial class UserControl1 : UserControl 
{ 
    public UserControl1() 
    { 
     InitializeComponent(); 
     outergrid.RowDefinitions[1].SetBinding(RowDefinition.HeightProperty, new Binding() { Path = new PropertyPath("ShowCode"), Source = this, Converter = new BoolToHeightConverter(), ConverterParameter = "True" }); 
    } 

    public bool ShowCode 
    { 
     get { return (bool)GetValue(ShowCodeProperty); } 
     set { SetValue(ShowCodeProperty, value); } 
    } 

    public static readonly DependencyProperty ShowCodeProperty = 
     DependencyProperty.Register("ShowCode", 
     typeof(bool), 
     typeof(UserControl1), 
     new PropertyMetadata(true, new PropertyChangedCallback(OnShowCodeChanged))); 

    static void OnShowCodeChanged(object sender, DependencyPropertyChangedEventArgs args) 
    { 
     UserControl1 source = (UserControl1)sender; 

     //source.outergrid.RowDefinitions[1].Height = 
    } 

    public class BoolToHeightConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, 
      object parameter, System.Globalization.CultureInfo culture) 
     { 
      if ((string)parameter == "False") return "0"; 
      return "1*"; 
     } 

     public object ConvertBack(object value, Type targetType, 
      object parameter, System.Globalization.CultureInfo culture) 
     { 
      if ((int)parameter == 0) return false; 
      return true; 
     } 
    } 
} 

문제

<xamlviewer:UserControl1 ShowCode="False"/> 

변환 (...)라고합니다 2 배 및 두 번 "매개 변수 er "은"True ", 그렇지 않으면 ShowCode ="True "일 때만 Convert()가 한 번만 호출되고"매개 변수 "가 다시"참 "이됩니다.

왜 항상 true입니까? 당신이 그 값을 가지고 만들었 기 때문에

답변

1

적어도 두 가지가 잘못되었습니다.

  1. 변환기는 GridLength을 반환해야하는 문자열을 반환합니다.

  2. 변환 할 값은 parameter이 아니라 변환기의 value 매개 변수로 전달되며 bool입니다.

그래서 당신이 작성해야 :

public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
{ 
    if (value is bool && (bool)value) 
    { 
     return new GridLength(1, GridUnitType.Star); 
    } 

    return new GridLength(0); 
} 

없음 변환 매개 변수가 바인딩에 필요하지 않습니다 :

outergrid.RowDefinitions[1].SetBinding(
    RowDefinition.HeightProperty, 
    new Binding() 
    { 
     Path = new PropertyPath("ShowCode"), 
     Source = this, 
     Converter = new BoolToHeightConverter() 
    }); 
1

매개 변수는 항상 true입니다 :

outergrid.RowDefinitions[1].SetBinding(
    RowDefinition.HeightProperty, 
    new Binding() 
    { 
     Path = new PropertyPath("ShowCode"), 
     Source = this, 
     Converter = new BoolToHeightConverter(), 
     ConverterParameter = "True" // <---- You are enforcing its value here. 
    }); 

귀하의 변환기 어쨌든 엉망 : 제대로 앞뒤로 데이터를 변환 parametervalue을하지 확인해야 :

// NOTE: Your property is BOOL not STRING. 
public class BoolToHeightConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, 
     object parameter, System.Globalization.CultureInfo culture) 
    { 
     if(value is bool) 
      if((bool)value) return new GridLength(1, DataGridLengthUnitType.Star); 
      else return new GridLength(0); 

     throw new ArgumentException("Not a bool"); 
    } 

    public object ConvertBack(object value, Type targetType, 
     object parameter, System.Globalization.CultureInfo culture) 
    { 
     // You may not need this method at all! 
     if(value is GridLength) 
      return ((GridLength)value).Value == 0); 
     throw new ArgumentException("Not a GridLength"); 
    } 
} 

매개 변수가 더 이상 필요하지 않습니다 (다른 곳에 필요가없는 경우).

관련 문제