我有一个角色对象,其中我有10个阵列,代表10个角色的统计数据(敏捷,力量等 - 这是一个角色扮演游戏)。阵列跟踪统计数据并随着时间的推移逐渐增加,因此我知道他们在哪个级别增加了哪个统计数据。数组是有限的,我跟踪到50级,所以我不需要能够跟踪可变数量的行或列。一切都是固定的。
e.g。 string [] Agility = new string [50];
我想在DataGrid中显示此信息,并将每行中的每个单元格绑定到每个stat数组的元素。我发现并尝试了我认为最好的希望,一个名为DataGrid2D的库,但是无法让我尽力而为。当我尝试更改DataGrid中的值时,我会收到错误:双向绑定需要Path或XPath。当我从ListBox中选择角色时,填充了10x50网格,甚至需要花费几秒钟来填充。
在此处找到了DataGrid2D示例:How to populate a WPF grid based on a 2-dimensional array。我使用了Meleak的答案(第二个下来),更改了m_intArray,用于从每个统计数据创建的2D数组(c.Stats)。
var c = CE_Characters_charactersLB.SelectedItem as Character;
var dg = CE_Characters_statsDG;
dg.ItemsSource = GetBindable2DArray<string>(c.Stats);
是否有更高效的解决方案?或者有人知道我为什么用DataGrid2D得到Path错误吗?
答案 0 :(得分:0)
从您发布的链接:“它是DataGrid的子类,并添加一个名为ItemsSource2D的属性,用于绑定2D或1D源”
所以我猜你必须使用该库提供的DataGrid并使用ItemsSource2D属性
答案 1 :(得分:0)
我瘦你的意思是敏捷= {10,5}和强度= {5,10}会指定一个快速弱的角色和一个相对强烈的缓慢角色。
class Stat
{
public Int Agility { get; set; }
public Int Strength { get; set; }
public Int HorseArmour { get; set; }
public Stat()
{
//Constructor
}
}
和
Public ObservableCollection<Stat> Stats { get; set; } //or list, but we'll be binding in a minute
与
Binding="{Binding Path=Agility}" //(agility being an example)
如果您在xam中设置列,则为您的列。 这在你的数据网格上:
ItemsSource="{Binding}"
答案 2 :(得分:0)
我有类似的问题,请看我的帖子: Two Way EntityCollection Binding to a Two Dimension Data Matrix
对于我也有一个固定的amout并想要一个TwoWay Binding,我定义了一个固定的Columns和Rout,并将Column和Row属性动态分配给ItemsControl中的TextBlock。
继承守则
<ItemsControl ItemsSource="{Binding Path=CustomerTankDayStructure,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
Grid.Column="1"
Grid.Row="2">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid helper:EnterKeyTraversal.IsEnabled="True"
KeyboardNavigation.TabNavigation="Local">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0" />
[...]
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0" />
<RowDefinition Height="30" />
[...]
<RowDefinition Height="30" />
</Grid.RowDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Grid.Column" Value="{Binding Path=DoW}" />
<Setter Property="Grid.Row" Value="{Binding Path=HoD}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="0,0,1,1"
Style="{StaticResource ResourceKey=DefaultBorder}">
<TextBox BorderThickness="0"
MaxLength="3"
Style="{StaticResource ResourceKey=EditableTextBoxWithoutWarningForTanks}"
TextAlignment="Center"
VerticalContentAlignment="Center"
IsTabStop="True">
<TextBox.TabIndex>
<MultiBinding Converter="{StaticResource ResourceKey=CustomerTankTabIndexConverter}">
<Binding Path="DoW" />
<Binding Path="HoD" />
</MultiBinding>
</TextBox.TabIndex>
<TextBox.Text>
<Binding Path="Value"
Mode="TwoWay"
NotifyOnValidationError="True"
TargetNullValue=""
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<validator:Int32Validator Mandatory="True"
Min="0"
Max="100" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
它有点“脏代码”,但对于这个问题,我没有找到任何其他解决方案:)
答案 3 :(得分:0)
我花了很长时间才弄清楚你的计划无法正常运作的原因。
基本上如果我是正确的,你的角色类看起来像这样:
public class Character
{
public string Name { get; set; }
public int Level { get; set; }
public int[] Agility { get; set; }
public int[] Strength { get; set; }
public int[] Stamina { get; set; }
public int[] Intelligence { get; set; }
}
Datagrid不使用这些stat属性的原因,因为它们彼此分开。它不知道如何基于几个不同的属性创建行。
正如Nathan Cooper之前所指出的,你真正需要的是另一个名为Stat(或类似的东西)的类,它可以将每个属性作为整数存储。然后,您需要这些类的集合来绑定您的数据网格。
这样想。您目前将数据垂直分组到列中。 Datagrids用于将数据分组为行。所以你需要一组代表一行的对象。
我花时间创建了一个示例应用程序,它将显示该概念的工作原理。
角色类看起来像这样:
public class Character
{
public string Name { get; set; }
public int Level { get; set; }
public List<Stat> Stats { get; set; }
public Character()
{
}
public class Stat
{
public int Agility { get; set; }
public int Strength { get; set; }
public int Intelligence { get; set; }
public int Stamina { get; set; }
}
}
在这里你可以看到我创建了一个类似于Nathan所说的Stat类。就像我说的那样,这个类将包含数据网格的“行”,因此数据可以按照数据网格易于理解的方式进行分组。
表单的XAML如下所示:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<ComboBox Margin="5,5,5,5" DisplayMemberPath="Name" Grid.Row="0" ItemsSource="{Binding Path=Characters}" SelectedItem="{Binding Path=SelectedCharacter}"></ComboBox>
<DataGrid Grid.Row="1" Margin="5,5,5,5" AutoGenerateColumns="True" ItemsSource="{Binding Path=SelectedCharacter.Stats}" >
<DataGrid.Columns>
<DataGridTextColumn Header="Agility" Binding="{Binding Path=Agility}"></DataGridTextColumn>
<DataGridTextColumn Header="Strength" Binding="{Binding Path=Strength}"></DataGridTextColumn>
<DataGridTextColumn Header="Intelligence" Binding="{Binding Path=Intelligence}"></DataGridTextColumn>
<DataGridTextColumn Header="Stamina" Binding="{Binding Path=Stamina}"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
我创建了一个组合框,它将选择要在DataGrid中显示的字符。此字符统计信息绑定到数据网格的列。
最后这里是ViewModel(不确定你是否正在使用MVVM,但是你应该这么做。无论如何,这些代码可以放在后面的代码中,几乎不需要更改):
public class MainWindowViewModel:ViewModelBase
{
private IList<Character> _characters;
public IList<Character> Characters
{
get
{
return _characters;
}
set
{
_characters = value;
RaisePropertyChanged(()=>Characters);
}
}
private Character _character;
public Character SelectedCharacter
{
get
{
return _character;
}
set
{
_character = value;
RaisePropertyChanged(()=>SelectedCharacter);
}
}
public MainWindowViewModel()
{
InitializeCharacters();
}
private void InitializeCharacters()
{
Characters = new List<Character>();
SelectedCharacter = new Character();
Characters.Add(new Character
{
Name = "Tank",
Level = 3,
Stats = new List<Character.Stat>()
{
new Character.Stat()
{
Agility = 10,
Intelligence = 8,
Strength = 14,
Stamina = 16
},
new Character.Stat()
{
Agility = 11,
Intelligence = 9,
Strength = 16,
Stamina = 18
},
new Character.Stat()
{
Agility = 12,
Intelligence = 10,
Strength = 17,
Stamina = 20
}
}
});
Characters.Add(new Character
{
Name = "Healer",
Level = 4,
Stats = new List<Character.Stat>()
{
new Character.Stat()
{
Agility = 10,
Intelligence = 14,
Strength = 8,
Stamina = 10
},
new Character.Stat()
{
Agility = 11,
Intelligence = 16,
Strength = 9,
Stamina = 11
},
new Character.Stat()
{
Agility = 12,
Intelligence = 17,
Strength = 10,
Stamina = 13
},
new Character.Stat()
{
Agility = 14,
Intelligence = 20,
Strength = 10,
Stamina = 14
}
}
});
Characters.Add(new Character
{
Name = "Ranger",
Level = 6,
Stats = new List<Character.Stat>()
{
new Character.Stat()
{
Agility = 12,
Intelligence = 8,
Strength = 10,
Stamina = 8
},
new Character.Stat()
{
Agility = 14,
Intelligence = 9,
Strength = 11,
Stamina = 10
},
new Character.Stat()
{
Agility = 17,
Intelligence = 10,
Strength = 12,
Stamina = 11
},
new Character.Stat()
{
Agility = 18,
Intelligence =11,
Strength = 13,
Stamina = 12
},
new Character.Stat()
{
Agility = 20,
Intelligence = 12,
Strength = 15,
Stamina = 13
},
new Character.Stat()
{
Agility = 22,
Intelligence = 13,
Strength = 16,
Stamina = 13
}
}
});
}
}
ViewModel中的大部分空间都由我创建虚拟数据,所以如果您愿意,可以随意删除它。重要的部分是创建SelectedCharacter和Characters Classes。
这是项目的链接,因此您可以看到它的实际效果。 (请原谅我名字不好的名字) https://docs.google.com/open?id=0B9JOiSJxT9vjZVl1SHd3UzBiZEE
祝你好运
U_U