0

そこで、プロパティの使用方法を学ぶために、「ShowCode」プロパティを使用してuserControlを作成しました。このプロパティでグリッドの2番目の行を非表示にします。

意見:

    <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()が1回だけ呼び出され、「parameter」が再び「True」の場合

なぜそれは常に真実なのですか?

4

2 に答える 2

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

とにかくコンバーターが台無しになっています。データを適切に前後に変換し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

ここでは少なくとも2つのことが間違っています。

  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 に答える