2

ターゲットのプロパティ情報( type や values など)で構成されるクラスがあります。このUIを使用して、ビュー上のすべてのタイプをコンボボックス付きのEnumやチェックボックス付きのブール値などのグラフィカル形式で表示しています。UIでコンボボックスの値を変更した場合を除いて、すべてがうまく機能します。コンボボックスでは、コンバーターの convertback メソッドを呼び出します。この文字列を列挙型に変換する必要があります。特定の列挙型の convertback コードを簡単に記述できますが、このコンバーターで他のすべての列挙型を変換するにはどうすればよいですか?コンバーターに渡して使用できる PropertyType プロパティを入力しますが、その方法がわかりません。

これは私のUIコードです(関連部分のみ)

    <!-- Default DataTemplate -->
    <DataTemplate x:Key="DefaultDataTemplate">
        <Grid Margin="4" MinHeight="25">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" SharedSizeGroup="Key" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding Name}"  FontWeight="Bold"  />
            <TextBox Margin="8,0" Grid.Column="1" Text="{Binding Value}"  />
        </Grid>
    </DataTemplate>

    <!-- DataTemplate for Booleans -->
    <DataTemplate x:Key="BooleanDataTemplate">
        <Grid Margin="4" MinHeight="25">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" SharedSizeGroup="Key" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding Name}" FontWeight="Bold"  />
            <CheckBox Margin="8,0" Grid.Column="1" IsChecked="{Binding Value}" />
        </Grid>
    </DataTemplate>



    <!-- DataTemplate for Enums -->
    <DataTemplate x:Key="EnumDataTemplate">
        <Grid Margin="4" MinHeight="25">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" SharedSizeGroup="Key" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding Name}" FontWeight="Bold"  />
            <ComboBox Margin="8,0" SelectedItem="{Binding Value,Converter={StaticResource EnumToStringConverter},Mode=TwoWay}" 
                      ItemsSource="{Binding PropertyType, 
                      Converter={local:EnumToListConverter}}" Grid.Column="1"  
                      HorizontalAlignment="Stretch" />
        </Grid>
    </DataTemplate>

    <!-- DataTemplate Selector -->
    <local:PropertyDataTemplateSelector x:Key="templateSelector"
          DefaultnDataTemplate="{StaticResource DefaultDataTemplate}"
          BooleanDataTemplate="{StaticResource BooleanDataTemplate}" 
          EnumDataTemplate="{StaticResource EnumDataTemplate}"/>
</Window.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"></RowDefinition>
        <RowDefinition  Height="*"></RowDefinition>
        <RowDefinition  Height="*"></RowDefinition>
    </Grid.RowDefinitions>
    <ListView Grid.Row="0" ItemsSource="{Binding Model,Converter={StaticResource PropConverter}, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}" Grid.IsSharedSizeScope="True" 
             HorizontalContentAlignment="Stretch" 
             ItemTemplateSelector="{StaticResource templateSelector}"
             />

そして私のコンバーターとビューモデル

  public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {

        string EnumString;
        try
        {
            EnumString = Enum.GetName((value.GetType()), value);
            return EnumString;
        }
        catch
        {
            return string.Empty;
        }
    }



    public object ConvertBack(object value, Type targetType,
      object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
        //What to do here
    }

モデルを見る

public class PropertyValue
{
    private PropertyInfo propertyInfo;
    private object baseObject;

    public PropertyValue(PropertyInfo propertyInfo, object baseObject)
    {
        this.propertyInfo = propertyInfo;
        this.baseObject = baseObject;
    }

    public string Name
    {
        get { return propertyInfo.Name; }

    }

    public Type PropertyType { get { return propertyInfo.PropertyType; } }

    public object Value
    {
        get { return propertyInfo.GetValue(baseObject, null); }
        set
        {

            propertyInfo.SetValue(baseObject, value , null);


        }
    }



}
4

5 に答える 5

0

ConvertBack では、targetType は正しい列挙型ですか?

もしそうなら、私はこれがうまくいくと思います:

Enum.Parse(targetType, (String)value)
于 2013-08-27T04:56:54.833 に答える
0

あなたはこのようにすべきです

enum Colors { Red = 1, Green = 2, Blue = 4, Yellow = 8 };
string colorName = "Blue";
if (Enum.IsDefined(typeof(Colors), colorName))  //true
 {
     Colors clr = (Colors)Enum.Parse(typeof(Colors), colorName);
 }

 colorName = "Orange";
 if (Enum.IsDefined(typeof(Colors), colorName)) //false
 {
      Colors clr = (Colors)Enum.Parse(typeof(Colors), colorName);
 }
于 2013-08-27T05:20:21.390 に答える
0

コンバーターまたはマルチバインディングでこれを実行できるとは思いません。コンボボックスにコンバーターを使用せず、ゲッターとセッターの値をチェックすることで問題を解決しました。

プロパティ情報を保持するクラスを変更しましたが、現在は機能しています。列挙型、コンバーターを使用できる残りの型に特別なチェックを入れています。

public class PropertyValue
{
    private PropertyInfo propertyInfo;
    private object baseObject;

    public PropertyValue(PropertyInfo propertyInfo, object baseObject)
    {
        this.propertyInfo = propertyInfo;
        this.baseObject = baseObject;
    }

    public string Name
    {
        get { return propertyInfo.Name; }

    }

    public Type PropertyType
    {
        get { return propertyInfo.PropertyType; }
    }

    public object Value
    {
        get
        {
            var retVal = propertyInfo.GetValue(baseObject, null);
            if (PropertyType.IsEnum)
            {
                retVal = retVal.ToString();
            }
            return retVal;
        }
        set
        {
            if (PropertyType.IsEnum)
            {
                value = Enum.Parse(propertyInfo.PropertyType, value.ToString());
            }
            propertyInfo.SetValue(baseObject, value, null);
        }
    }
}

そのためのビューモデルの破損は好きではありませんが、現時点ではオプションが表示されません。コードにリスクがあるか、またはより良いアプローチがあるかどうかをお知らせください。

于 2013-08-27T07:37:00.670 に答える