【问题标题】:WPF C# Binding label to DataGrid containing ObervableCollection of custom objectsWPF C# 将标签绑定到包含自定义对象的 ObervableCollection 的 DataGrid
【发布时间】:2014-05-21 17:21:01
【问题描述】:

好的,这是我的问题。我正在为我的 RPG 系统创建一个简单的应用程序。这是一个可以创建英雄和查看统计数据的玩家的角色图表。所以,下面是 Hero 基类的重要内容:

namespace CharacterChart.Classes
{
[DataContract(Name = "Character", Namespace = "http://www.jambs.com")]
abstract class Base : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    [DataMember]
    private string Name;

    [DataMember]
    public ObservableCollection<Attribute> Attributes;

    protected void OnPropertyChanged(string info)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(info));
        }
    }
    public Base()
    {
        this.Name = "Nowa postać";
        Attributes = new ObservableCollection<Attribute>();
        Attributes.Add(new Attribute { Key = 'S', Value = 0 });
        Attributes.Add(new Attribute { Key = 'Z', Value = 0 });
        Attributes.Add(new Attribute { Key = 'P', Value = 0 });
        Attributes.Add(new Attribute { Key = 'B', Value = 0 });
        Attributes.Add(new Attribute { Key = 'C', Value = 0 });
        Attributes.Add(new Attribute { Key = 'I', Value = 0 });
        Attributes.Add(new Attribute { Key = 'W', Value = 0 });
        Attributes.Add(new Attribute { Key = 'D', Value = 0 });
    }

    public string name
    {
        get { return Name; }
        set { Name = value; OnPropertyChanged("Name"); }
    }

    public ObservableCollection<Attribute> attributes
    {
        get { return Attributes; }
        set { Attributes = value; OnPropertyChanged("Attributes"); }
    }
}
}

这是 Attribute 类的代码(我想使用 Dictionary,但它不包含 OnPropertyChanged):

 class Attribute : INotifyPropertyChanged
 {
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string info)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(info));
        }
    }

    [DataMember]
    private char key;

    [DataMember]
    private byte number;

    public char Key
    {
        get { return key; }
        set { key = value; OnPropertyChanged("Key"); }

    }
    public byte Value
    {
        get { return number; }
        set { number = value; OnPropertyChanged("Value"); }
    }
}

在主程序中,我声明英雄的 ObservableCollection 并为 Datagrid 设置 ItemsSource。在 XAML 中是这样的:

<DataGrid Name="DataHeroes" Grid.Column="0" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding Path=name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
            <DataGridTextColumn Header="Strength" Binding="{Binding Path=attributes[0].Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        </DataGrid.Columns>
    </DataGrid>

现在我想添加一个功能,让我在 DataGrid 中选择一个英雄,然后显示他的所有统计数据。不幸的是,显示属性对我不起作用。这是我尝试过的:

<TextBlock Text="{Binding ElementName=DataHeroes, Path=SelectedIndex.attributes[0].Value, Mode=OneWay}" Grid.Column="2"/>

任何想法我应该如何引用我的属性集合并显示选定的一个?

此示例仅涉及单个属性,稍后我将对其进行扩展。

【问题讨论】:

  • 一个带有修辞回答的好问题:将 DataGrid 的 SelectedValue 绑定到视图模型中的属性,然后将 Textblock 绑定到该属性的属性 [0]...不要忘记使用 IsSynchronizedWithCurrentItem=true
  • @GayotFow 这是一种方法,或者您可以将 SelectedItem 与 ElementName 一起使用(链接足够多次,您可以用很少/没有代码隐藏来做一些非常酷的事情)
  • @BradleyDotNET,是的,但随后警告他,如果在 SelectedItem 是源时选择了多个项目会发生什么:)
  • @GayotFow,谢谢!添加到我的答案中。

标签: c# wpf binding wpfdatagrid


【解决方案1】:

SelectedIndex 返回一个整数,它显然没有“属性”属性。将您的行更改为:

<TextBlock Text="{Binding ElementName=DataHeroes, Path=SelectedItem.attributes[0].Value, Mode=OneWay}" Grid.Column="2"/>

SelectedItem 返回在 UI 上选择的绑定对象。 (MSDN)

请注意,如果选择了多个项目,这将返回第一个用户选择的项目。

【讨论】:

  • +1 表示多选问题的完整性
  • 谢谢。我在其他程序中做了完全相同的事情,但我复制错了。我检查了数百次,仍然找不到它不起作用的原因。 :D 现在好了,再次感谢。
猜你喜欢
  • 1970-01-01
  • 2010-12-16
  • 2011-01-12
  • 2011-10-17
  • 1970-01-01
  • 2012-02-23
  • 2015-03-27
  • 2012-11-16
  • 2012-03-15
相关资源
最近更新 更多