数据绑定列表框中选定项的 WPF 嵌套属性

本文关键字:WPF 嵌套 属性 列表 数据绑定 | 更新日期: 2023-09-27 18:34:19

我自己尝试解决这个问题,在堆栈溢出上查看了几种可能的解决方案,但唉,我一直无法解决这个问题。


DR版本:

问题:

使用数据绑定显示 RPG 字符列表的列表框,这些角色的属性具有嵌套属性。由于嵌套属性和数据绑定的限制,我无法显示属性。下面的代码与该问题相关。


我有一个列表框,它有一个数据绑定,用于控制列表中显示的内容。数据绑定将 ObservableCollection 用于列表包含的对象列表。所有这些都工作正常,但与手头的问题有关。

listBox 数据绑定在每个元素中都有几个嵌套属性,我想在窗体中显示和更改这些属性,但我无法使嵌套数据绑定正常工作。

这是列表框 XAML:

<ListBox x:Name="listCharacters" Margin="2,0" ItemsSource="{Binding}" Grid.Row="1" ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Hidden" SelectionChanged="listCharacters_SelectionChanged">
    <ListBox.ItemTemplate>
        <DataTemplate DataType="{x:Type local:Character}" x:Name="Symchar">
            <Grid Width="125" HorizontalAlignment="Left" Background="{x:Null}">
                <Grid.RowDefinitions>
                    <RowDefinition Height="18"/>
                    <RowDefinition Height="12"/>
                    <RowDefinition Height="16"/>
                </Grid.RowDefinitions>
                <Image Panel.ZIndex="5" HorizontalAlignment="Right" VerticalAlignment="Top" Height="16" Width="16" Margin="0,2,0,0" Source="Resources/1454889983_cross.png" MouseUp="DeleteCharacter" />
                <TextBlock Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" FontWeight="Bold" FontSize="13.333" Grid.Row="0" TextTrimming="CharacterEllipsis" Padding="0,0,16,0" />
                <TextBlock Text="{Binding RealRace.Label, UpdateSourceTrigger=PropertyChanged}" FontSize="9.333" Grid.Row="1" FontStyle="Italic" />
                <TextBlock FontSize="9.333" Grid.Row="2" HorizontalAlignment="Left" VerticalAlignment="Top">
                    <Run Text="{Binding RealClass.Archetype.Label, UpdateSourceTrigger=PropertyChanged}"/>
                    <Run Text=" - "/>
                    <Run Text="{Binding RealClass.Label, UpdateSourceTrigger=PropertyChanged}"/>
                </TextBlock>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

并设置列表框项源:

this.listCharacters.ItemsSource = CharacterList;

这是字符类,我删除了不相关的代码(XML 序列化属性等(

public class Character : INotifyPropertyChanged
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            this.NotifyPropertyChanged("Name");
        }
    }
    private string _player;
    public string Player
    {
        get { return _player; }
        set
        {
            _player = value;
            this.NotifyPropertyChanged("Player");
        }
    }
    private string _race;
    public string Race
    {
        get { return _race; }
        set
        {
            _race = value;
            this.NotifyPropertyChanged("Race");
        }
    }
    private Race _realRace;
    public Race RealRace
    {
        get { return _realRace; }
        set
        {
            _realRace = value;
            Race = value.Id;
            this.NotifyPropertyChanged("RealRace");
        }
    }
    private string _gender;
    public string Gender
    {
        get { return _gender; }
        set
        {
            _gender = value;
            this.NotifyPropertyChanged("Gender");
        }
    }
    private Attributes _attributes;
    public Attributes Attributes
    {
        get { return _attributes; }
        set
        {
            _attributes = value;
            this.NotifyPropertyChanged("Attributes");
        }
    }
    private string _class;
    public string Class
    {
        get { return _class; }
        set
        {
            _class = value;
            this.NotifyPropertyChanged("Class");
        }
    }
    private Class _realClass;
    public Class RealClass
    {
        get { return _realClass; }
        set
        {
            _realClass = value;
            Class = value.Id;
            this.NotifyPropertyChanged("RealClass");
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

为了简单起见,我一直在测试的属性是"属性"属性,这是它的代码:

public class Attributes : INotifyPropertyChanged
{
    private int _accurate;
    public int Accurate
    {
        get { return _accurate; }
        set
        {
            _accurate = value;
            this.NotifyPropertyChanged("Accurate");
        }
    }
    private int _cunning;
    public int Cunning
    {
        get { return _cunning; }
        set
        {
            _cunning = value;
            this.NotifyPropertyChanged("Cunning");
        }
    }
    private int _discreet;
    public int Discreet
    {
        get { return _discreet; }
        set
        {
            _discreet = value;
            this.NotifyPropertyChanged("Discreet");
        }
    }
    private int _persuasive;
    public int Persuasive
    {
        get { return _persuasive; }
        set
        {
            _persuasive = value;
            this.NotifyPropertyChanged("Persuasive");
        }
    }
    private int _quick;
    public int Quick
    {
        get { return _quick; }
        set
        {
            _quick = value;
            this.NotifyPropertyChanged("Quick");
        }
    }
    private int _resolute;
    public int Resolute
    {
        get { return _resolute; }
        set
        {
            _resolute = value;
            this.NotifyPropertyChanged("Resolute");
        }
    }
    private int _strong;
    public int Strong
    {
        get { return _strong; }
        set
        {
            _strong = value;
            this.NotifyPropertyChanged("Strong");
        }
    }
    private int _vigilant;
    public int Vigilant
    {
        get { return _vigilant; }
        set
        {
            _vigilant = value;
            this.NotifyPropertyChanged("Vigilant");
        }
    }
    private int _toughness;
    public int Toughness
    {
        get { return _toughness; }
        set
        {
            _toughness = value;
            this.NotifyPropertyChanged("Toughness");
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

当选择 listBox 中的字符时,我想在字段中显示每个单独的属性,这可以直接在字符类中处理属性,但由于嵌套属性和数据绑定的限制,我无法让它与"属性"属性值一起使用。

属性输入字段之一的 XAML:

<TextBox x:Name="attr_Accurate" DataContext="{Binding Path=(local:Character.Attributes), XPath=SelectedItem, ElementName=listCharacters, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Text="{Binding Path=(local:Accurate)}" PreviewTextInput="NumericInput"/>

UpdateSourceTrigger 只是一种只允许在字段中输入整数的方法:

private void NumericInput(object sender, TextCompositionEventArgs e)
{
    if (!char.IsDigit(e.Text, e.Text.Length - 1))
    {
        e.Handled = true;
    }
}

如果有人能帮助我通过数据绑定显示所选字符属性中的值,我将不胜感激。

数据绑定列表框中选定项的 WPF 嵌套属性

按如下方式使用绑定:

要显示Accurate属性值,请执行以下操作:

<TextBox x:Name="attr_Accurate" Text="{Binding Path=SelectedItem.Attributes.Accurate), ElementName=listCharacters, Mode=OneWay}"  PreviewTextInput="NumericInput"/>

要显示Cunning属性值,请执行以下操作:

<TextBox x:Name="attr_Accurate" Text="{Binding Path=SelectedItem.Attributes.Cunning), ElementName=listCharacters, Mode=OneWay}"  PreviewTextInput="NumericInput"/>

等等。

(我不确定你是希望绑定是双向还是一种,所以请 根据需要更改(