在数据网格中显示字符串时遇到一些问题。
解释代码:我将一组士兵绑定到一个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";
}
结果:
答案 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>