0

所以我创建了一个带有“ShowCode”属性的用户控件来学习如何使用属性。我希望此属性隐藏网格中的第二行。

看法:

    <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"/>

Convert(...) 被调用 2 次并且两次“参数”都是“True”,否则如果 ShowCode="True" Convert() 只被调用一次并且“parameter”又是“True”

为什么总是正确的?

4

2 回答 2

1

参数始终为真,因为您使其具有该值:

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.
    });

无论如何,您的转换器都搞砸了:您必须检查是否value不能parameter正确地来回转换数据:

// 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");
    }
}

不再需要参数(除非您在其他地方有其他需要)。

于 2012-12-19T12:54:05.463 回答
1

这里至少有两件事是错误的。

  1. 您的转换器返回一个字符串,它应该返回一个GridLength

  2. 要转换的值是传递给转换器的value参数,而不是传递给parameter它,它是一个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()
    });
于 2012-12-19T12:55:17.180 回答