WPF:更新列表框项目中的标签

发布于 2024-07-09 13:39:27 字数 914 浏览 4 评论 0原文

我有一个 ListBox,其中根据用户设置的整数属性添加项目数量。 这些项目是从 ControlTemplate 资源创建的,该资源由 DockPanel 内部的 Label 和 TextBox 组成。 该标签不是数据绑定的,但我希望它具有基于它所包含的 ListboxItem 的 (index + 1) 的动态内容。 我的问题是我希望能够更新每个 ListboxItem 的标签内容,但由于某种原因无法访问该标签。 我不知道有什么方法可以通过标签的数据绑定来做到这一点,因为标签位于模板中,并且不知道它的父级是 ListboxItem。 谁能帮助我消除一些困惑,让我回到正确的轨道上?

<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>

我希望能够在xaml中绑定Label的内容,或者在后面的代码中更新Label的内容。 我不确定最好的路线是什么。

I have a ListBox where the number of items is added based on and integer property set by a user. The items are created from a ControlTemplate resource that which is comprised of a Label and a TextBox inside of a DockPanel. The label is not data bound but I would like for it to have somewhat dynamic content based on the (index + 1) of the ListboxItem for which it is contained. My question/problem is that I want to be able update the content of the label for each ListboxItem, but cannot access the label for some reason. I am unaware of any way to do this through data-binding of the label since the label is in a template and has no knowledge that it has a parent that is a ListboxItem. Can anyone help me clear up some of these confusions to get me back on the right 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 of the Label in xaml, or update the content of the Label in the code behind. I'm not sure what the best route would be.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

肥爪爪 2024-07-16 13:39:27

更新:最初我试图在模板中找到这样的Label...

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

我发现你必须调用ApplyTemplate()才能构建模板的视觉树之前它就能找到该元素。

UPDATE: Initially I was trying to find the Label in the template like this....

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

I found out that you have to call ApplyTemplate() in order to build the template's visual tree before it will be able to find the element.

烂柯人 2024-07-16 13:39:27

您必须创建一个 IMultiValueConverter 来获取模板的索引:

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();
    }
}

然后您应该在 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>

You have to create an IMultiValueConverter that will get 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();
    }
}

You should then use the converter into your 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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文