WPF: update shortcut on list item

I have ListBox

where the number of items is added based on and a user-defined integer property. Items are created from a resource ControlTemplate

that consists of a label and a TextBox

inside DockPanel

. The label is not data bound, but I would like it to have somewhat dynamic content based on the (index + 1) ListboxItem

it is contained for. My question / problem is that I want to update the content of the label for each ListboxItem

, but for some reason I can't access the label. I don't know how to do this through data binding to the label, since the label is in the template and doesn't know that it has a parent which is ListboxItem

. Can anyone help me clear up some of these misunderstandings to get me back on track, please?

<ControlTemplate TargetType="{x:Type ListBoxItem}">
    <DockPanel Background="Transparent" Height="28" Name="playerDockPanel" VerticalAlignment="Bottom">
        <Label Name="playerNameLabel" DockPanel.Dock="Left" Content="Player"></Label>
        <TextBox Height="23" Width ="150" Name="playerName" DockPanel.Dock="Right"/>
    </DockPanel>
</ControlTemplate>

      

I would like to be able to bind the content Label

in the xaml or update the content Label

in the code behind. I'm not sure what the best route would be.

0


source to share


2 answers


UPDATE: At first I was trying to find Label

in the template like this ....

  Label label = (Label)lbi.Template.FindName("playerNameLabel",lbi);

      



I figured out what you have to call ApplyTemplate()

to build the visual template tree before it can find this item.

0


source


You need to create IMultiValueConverter

one that will receive the index of your template:

public class PositionConverter : IMultiValueConverter
{
    public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture)
    {
        ItemsControl itemsControl = value[0] as ItemsControl;
        UIElement templateRoot = value[1] as UIElement;
        if (templateRoot != null)
        {
            UIElement container = ItemsControl.ContainerFromElement(itemsControl, templateRoot) as UIElement;
            if (container != null)
            {
                return itemsControl.ItemContainerGenerator.IndexFromContainer(container);
            }
        }

        return null;
    }

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

      



Then you have to use the converter to yours DataTemplate

:

<DataTemplate x:Key="itemTemplate">
    <DockPanel Background="Transparent" Height="28" Name="playerDockPanel" VerticalAlignment="Bottom">
        <Label Name="playerNameLabel" DockPanel.Dock="Left" Content="{Binding Title}"></Label>
        <Label Height="23" Width ="150" Name="playerName" DockPanel.Dock="Right">
            <Label.Content>
                <MultiBinding Converter="{StaticResource positionConverter}">
                    <!-- The ItemsControl-->
                    <Binding ElementName="listBox" />
                    <!-- The root UIElement-->
                    <Binding ElementName="playerDockPanel"/>
                </MultiBinding>
            </Label.Content>                    
        </Label>
    </DockPanel>
</DataTemplate>

      

0


source







All Articles