Karl_Schuhmann
Karl_Schuhmann

Reputation: 1332

How to Bind on a Property by String as Propertyname

Hi i want to Bind to an "unknown" (i only get a string) Property in Xaml

at first i wrote an IValueConverter but you can't bind to ConverterParameter so i rewrite it as IMultiValueConverter but now i'm unable to figure out how to use the <Binding /> with out Path or my i'm wrong?

if you write <TextBlock Text="{Binding}" /> you will get the object Person and with {Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListView}}, Path=View.Columns[0].Header}} i'm able to access the Header Text of the first row

now i'm only need to combine both and a will get the Property right?

my test Xaml code:

<UserControl x:Class="Frameworktest.View.auswahl"
             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:local="clr-namespace:Frameworktest">
    <UserControl.Resources>
        <local:toPropertyConverter x:Key="PropertyConverter"/>
    </UserControl.Resources>
    <StackPanel>
        <!--...-->
        <Border BorderThickness="5" HorizontalAlignment="Left" VerticalAlignment="Top" 
                BorderBrush="Green" CornerRadius="5">
            <ListView  Name="listView1"  IsSynchronizedWithCurrentItem="False" 
                       ItemsSource="{Binding Items, UpdateSourceTrigger=PropertyChanged}" <!--ObservableCollection<Person>-->
                       SelectedItem="{Binding selectedItem, UpdateSourceTrigger=PropertyChanged}">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="Name">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock Margin="1">
                                        <TextBlock.Text>
                                            <MultiBinding Converter="{StaticResource PropertyConverter}">
                                                <Binding /><!-- How do i {Binding} here?-->
                                                <Binding Source="{Binding RelativeSource={Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListView}}, Path=View.Columns[0].Header}}" />
                                            </MultiBinding>
                                        </TextBlock.Text>
                                    </TextBlock>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>

                        <GridViewColumn Header="Firstname" >
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock Margin="1" Text="{Binding Path=Name}" Width="100"/><!--works-->
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>

                        </GridViewColumn>
                        <GridViewColumn Header="Age">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock Margin="1" Text="{Binding Age}" Width="50"/><!--works-->
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                   </GridView>
                </ListView.View>
            </ListView>
        </Border>
    </StackPanel>
</UserControl>

the Converter:

public class toPropertyConverter : IMultiValueConverter 
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return values[0].GetType().GetProperty((string)values[1]);
    }

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

The Model

public class Person : MBase, IContains
{
private string _name;

public string  Name
{
    get { return _name; }
    set { _name = value;
    RaisePropertyChanged(() => Reg(() => Name));
    }
}

private string _firstname;
public string  Firstname
{
    get { return _firstname; }
    set
    {
        _firstname = value;
        RaisePropertyChanged(() => Reg(() => Firstname));
    }
}

private int _age;

public int Age
{
    get { return _age; }
    set
    {
        _age = value;
        RaisePropertyChanged(() => Reg(() => Age));
    }
}

public bool Contains(string text)
{
    string pers = string.Format("{0} {1}", Firstname, Name);

    return pers.Contains(text);

}

}

Update my current Multibindung

<MultiBinding Converter="{StaticResource PropertyConverter}">
       <Binding Path="."/>
       <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ListView}}" Path="View.Columns[0].Header}}" /> <!-- doesn't contain the word "Name" like i suspected -->
</MultiBinding>

LAST Update

it is a dead end in my case you can't Bind from the GridViewColumn.CellTemplate to the specific Column Header Value

Upvotes: 0

Views: 2062

Answers (1)

Kek
Kek

Reputation: 3195

{Binding} implicitely means : {Binding Path=.}. So you could use

<Binding Path="."/>

Upvotes: 1

Related Questions