user2036256 user2036256 - 1 year ago 51
C# Question

Calling a method from the container class in binding

I effectively have -

<UserControl ...>
<Grid>
<TreeView Name="nTree">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="NodeType" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<Image x:Name="icon" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</UserControl>


NodeType is a type returned by an underlying library. I would like to set the icon images source based on the name provided - however I can't modify NodeType to add a getter.

So ideally what I would like is the icon image source to be bound to a function on the UserControl class which receives the Name and returns an ImageSource.

i.e.

public partial class Panel : UserControl
{
public Panel(NodeType n)
{
nTree.Items.add(n);
}

public ImageSource GetIcon(string name)
{
...
}
}


This feels like it should be possible but i'm struggling to work it out. Assistance would be appreciated.

Answer Source

Unfortunately you can't bind to methods, you need to convert the method to a property

you can do this in several ways

the easiest you be to have, (though this should be on your VM not your V)

public ImageSource Icon
{
    ...
}

or you can use a value converter(the best fit for what you are descibing)

public class ImageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        GetImageLogic
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException("One way only");
    }
}

the 3rd option would be to use an CommandBinding

then bind to the command

CommandBinding OpenCmdBinding = new CommandBinding(
    ApplicationCommands.Open,
    OpenCmdExecuted,
    OpenCmdCanExecute);

this.CommandBindings.Add(OpenCmdBinding);

void OpenCmdExecuted(object target, ExecutedRoutedEventArgs e)
{
    String command, targetobj;
    command = ((RoutedCommand)e.Command).Name;
    targetobj = ((FrameworkElement)target).Name;
    MessageBox.Show("The " + command +  " command has been invoked on target object " + targetobj);

}

void OpenCmdCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = true;
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download