将ComboBox SelectedItem绑定到Datagrid

时间:2014-08-16 22:53:48

标签: c# wpf binding datagrid selecteditem

在数据网格中显示字符串时遇到一些问题。

解释代码:我将一组士兵绑定到一个ComboBox。士兵有自己的武器集合。

当我在ComboBox中选择一个特定的士兵时,我希望在数据网格中显示该士兵的武器。我相信我绑定正确,但数据网格总是空白。谁知道我做错了什么?

XAML

<Grid>
    <ComboBox x:Name="Character_ComboBox" HorizontalAlignment="Left" VerticalAlignment="Top" Width="328" Height="25">
    </ComboBox>
</Grid>

<DataGrid x:Name="Character_items_datagrid" ItemsSource="{Binding ElementName=Character_ComboBox, Path= SelectedItem.Equipment, Mode=OneWay}" Margin="328,0,0,0" Grid.RowSpan="2" >
    <DataGrid.Columns>
        <DataGridTextColumn Header="Primary"  Binding="{Binding Primary, Mode=TwoWay}" FontWeight="Bold" Foreground="Black" Width="0.1*"></DataGridTextColumn>
        <DataGridTextColumn Header ="Secondary" Binding="{Binding Secondary, Mode=TwoWay}" Width="0.1*"></DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

士兵等级

public class Soldier 
{
    public string Soldier_Class { get; set; }
    public ObservableCollection<Weapons> Equipment { get; set; }
}

武器类

public class Weapons
{
    string Primary { get; set; }
    string Secondary { get; set; }

    public Weapons(string primary, string secondary)
    {
        this.Primary = primary;
        this.Secondary = secondary;
    }
}

主窗口

public ObservableCollection<Soldier> squad_members = new ObservableCollection<Soldier>();

public MainWindow()
{
    InitializeComponent();

    squad_members.Add(new Soldier() { Soldier_Class = "Assult Soldier", Equipment = new ObservableCollection<Weapons>() { new Weapons("M4 Rifle", "Compact 45 Pistol")}});
    squad_members.Add(new Soldier() { Soldier_Class = "SMG Soldier", Equipment = new ObservableCollection<Weapons>() { new Weapons("RPK Machine Gun", "HK Shotgun"), new Weapons("SAW Machine Gun", "Compact 45 Pistol")}});
    squad_members.Add(new Soldier() { Soldier_Class = "Juggernaut", Equipment = new ObservableCollection<Weapons>() { new Weapons("MP5", "Bowie Knife") }});

    Binding comboBinding = new Binding();
    comboBinding.Source = squad_members;

    BindingOperations.SetBinding(Character_ComboBox, ComboBox.ItemsSourceProperty, comboBinding);
    Character_ComboBox.DisplayMemberPath = "Soldier_Class";
    Character_ComboBox.SelectedValuePath = "Soldier_Class";
}

结果:

enter image description here

2 个答案:

答案 0 :(得分:1)

您需要在模型public中创建属性才能使绑定能够工作:

public class Weapons
{
    public string Primary { get; set; }
    public string Secondary { get; set; }
    .....
}

您的DataGrid看起来正确填充了项目,但每个项目的属性都没有在列中正确显示。这表明绑定引擎无法访问该项的属性,因为它具有private可访问性。

答案 1 :(得分:0)

你的主要问题是公共访问修饰符,正如har07所写。

还有很多其他事情你也可以改进。为您的类实现INotifyPropertyChanged,因此UI会立即反映对属性的任何更改。没有令人信服的理由,不要在代码中创建绑定。使用ViewModel绑定,而不是直接绑定到ComboBox.SelectedItem之类的元素。如果要为列设置样式,请将AutoGenerateColumns设置为false(您的代码将生成四列)。使用Grid.ColumnDefinitions而不是分配固定的保证金。

型号:

using System.Collections.ObjectModel;
using System.ComponentModel;

namespace WpfApplication1.ViewModels
{
    public class SquadViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        private ObservableCollection<Soldier> _squadMembers;
        public ObservableCollection<Soldier> SquadMembers { get { return _squadMembers; } set { _squadMembers = value; OnPropertyChanged("SquadMembers"); } }

        private Soldier _selectedSoldier;
        public Soldier SelectedSoldier { get { return _selectedSoldier; } set { _selectedSoldier = value; OnPropertyChanged("SelectedSoldier"); } }


        public SquadViewModel()
        {
            SquadMembers = new ObservableCollection<Soldier>()
            {
                new Soldier() { SoldierClass = "Assult Soldier", Equipment = new ObservableCollection<Weapon>() { new Weapon("M4 Rifle", "Compact 45 Pistol") } },
                new Soldier() { SoldierClass = "SMG Soldier", Equipment = new ObservableCollection<Weapon>() { new Weapon("RPK Machine Gun", "HK Shotgun"), new Weapon("SAW Machine Gun", "Compact 45 Pistol") } },
                new Soldier() { SoldierClass = "Juggernaut", Equipment = new ObservableCollection<Weapon>() { new Weapon("MP5", "Bowie Knife") } }
            };
        }
    }

    public class Soldier : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        private string _soldierClass;
        public string SoldierClass { get { return _soldierClass; } set { _soldierClass = value; OnPropertyChanged("SoldierClass"); } }

        private ObservableCollection<Weapon> _equipment;
        public ObservableCollection<Weapon> Equipment { get { return _equipment; } set { _equipment = value; OnPropertyChanged("Equipment"); } }
    }

    public class Weapon : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        private string _primary;
        string Primary { get { return _primary; } set { _primary = value; OnPropertyChanged("Primary"); } }

        private string _secondary;
        string Secondary { get { return _secondary; } set { _secondary = value; OnPropertyChanged("Secondary"); } }

        public Weapon(string primary, string secondary)
        {
            this.Primary = primary;
            this.Secondary = secondary;
        }
    }
}

的Xaml:

<Window x:Class="WpfApplication1.MainWindow"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:vm="clr-namespace:WpfApplication1.ViewModels"
                Title="MainWindow" Height="350" Width="580">

    <Window.DataContext>
        <vm:SquadViewModel />
    </Window.DataContext>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <ComboBox x:Name="CbxCharacter" HorizontalAlignment="Left" VerticalAlignment="Top" Width="328" Height="25"
                  ItemsSource="{Binding SquadMembers}" SelectedItem="{Binding SelectedSoldier}"
                  DisplayMemberPath="SoldierClass" SelectedValuePath="SoldierClass"/>

        <DataGrid x:Name="DgCharacterItems" ItemsSource="{Binding SelectedSoldier.Equipment, Mode=OneWay}" Grid.Column="1" AutoGenerateColumns="False"  >
            <DataGrid.Columns>
                <DataGridTextColumn Header="Primary" Binding="{Binding Primary, Mode=TwoWay}" FontWeight="Bold" Foreground="Black" Width="*" />
                <DataGridTextColumn Header="Secondary" Binding="{Binding Secondary, Mode=TwoWay}" Width="*" />
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>