WPF dynamic linking

Today I worked on a WPF UserControl to display the current value of several variables. I was wondering if there is a way to make a super-simple property grid in WPF. The problem is the highlighted XAML line below. How do I bind a string to a property using ItemTemplate, how do I have the setting below? To make it clearer, I can embed bindings inside each other {Binding Path={Binding Value}}.

Here is the class:

public class Food
{
    public string Apple { get; set; }
    public string Orange { get; set; }
    public IEnumerable<KeyValuePair<string, string>> Fields
    {
        get
        {
            yield return new KeyValuePair<string, string>("Apple Label", "Apple");
            yield return new KeyValuePair<string, string>("Orange Label", "Orange");
        }
    }
}

And here is the XAML:

<UserControl x:Class="MAAD.Plugins.FRACTIL.Simulation.SimulationStateView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="331" Width="553">
 <ListView ItemSource="{Binding Fields}">
  <ListView.ItemTemplate>
   <DataTemplate>
    <StackPanel Orientation="Horizontal">
     <TextBlock Text="{Binding Key}" />
     **<TextBlock Text="{Binding Path={Binding Value}}" />**
    </StackPanel>
   </DataTemplate>
  </ListView.ItemTemplate>
 </ListView>
</UserControl>
+3
source share
2 answers

The essence of the problem is that you need not only a list of descriptions and field names, but also the actual object that has these fields and names.

, , :

  public class PropertyValueAccessConverter : IMultiValueConverter
  {
    object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
      var target = values[0];
      var fieldList = values[1] as IEnumerable<KeyValuePair<string,string>>;
      return
        from pair in fieldList
        select new PropertyAccessor
        {
          Name = pair.Name,
          Target = target,
          Value = target.GetType().GetProperty(target.Value),
        };
    }

    object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
      throw new InvalidOperationException();
    }

    public class PropertyAccessor
    {
      public string Name
      public object Target;
      public PropertyInfo Property;

      public object Value
      {
        get { return Property.GetValue(Target, null); }
        set { Property.SetValue(Target, value, null); }
      }
    }

    public static PropertyValueAccessConverter Instance = new PropertyValueAccessConverter();
  }

ItemsSource :

  <ListView>
    <ListView.ItemsSource>
      <MultiBinding Converter="{x:Static local:PropertyValueAccessConverter.Instance}">
        <Binding />
        <Binding Path="Fields" />
      </MultiBinding>
    </ListView.ItemsSource>
  </ListView>

, Fields:

  public IEnumerable<KeyValuePair<string, string>> Fields
  {
    get
    {
      return new KeyValuePair<string, string>[]
      {
        new KeyValuePair<string, string>("Apple Label", "Apple");
        new KeyValuePair<string, string>("Orange Label", "Orange");
      }
    }
  }

, . MultiBinding .

+5

, :

<TextBlock Text="{Binding Path=Value}" />

, , , . , KeyValuePair INotifyPropertyChange ( , ), , . , KeyValuePair . , , .

, , KeyValuePair, View-Model, . - , (, ?) . , - ( , , ), , .

+1

Source: https://habr.com/ru/post/1721723/


All Articles