WPF DataGrid DataGridTemplateColumn

时间:2014-04-26 11:26:31

标签: wpf xaml binding datagrid combobox

我正在尝试显示数据网格名称和人的性别。用户应该能够输入名称并从组合框中选择性别。我希望组合框始终可见,所以我正在使用DataGridTemplateColumn。但是每当我将新人添加到列表中时,组合框中都不会显示性别,但我确定它已设置好。但是,如果我从组合框中选择任何内容,将显示选择,并且将更新模型上的数据。有什么可以使这项工作?注意:我正在使用Caliburn。

这是我的观点:

<Window x:Class="WpfPetApp.ShellView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>
        <DataGrid x:Name="TestDataGrid" Grid.Row="0" ColumnWidth="*" HeadersVisibility="Column" SelectedItem="{Binding SelectedTestDataGrid, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                        CanUserDeleteRows="False" 
                        CanUserAddRows="False" 
                        CanUserResizeColumns="False"
                        CanUserReorderColumns="False"
                        CanUserResizeRows="False"
                        CanUserSortColumns="True"
                        AutoGenerateColumns="False" 
                        SelectionMode="Single" >
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{Binding ElementName=TestDataGrid, Path=DataContext.Sexes}" SelectedValue="{Binding Sex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
        <Button x:Name="AddRow" Grid.Row="1">Add</Button>
    </Grid>
</Window>

视图模型:

public class ShellViewModel : PropertyChangedBase, IShell
{
    private Person _selectedTestDataGrid;

    public ObservableCollection<Person> TestDataGrid { get; set; }
    public ObservableCollection<Sex> Sexes { get; set; }

    public Person SelectedTestDataGrid
    {
        get { return _selectedTestDataGrid; }
        set
        {
            if (Equals(value, _selectedTestDataGrid)) return;
            _selectedTestDataGrid = value;
            NotifyOfPropertyChange(() => SelectedTestDataGrid);
        }
    }

    public ShellViewModel()
    {
        TestDataGrid = new ObservableCollection<Person>();
        Sexes = new ObservableCollection<Sex>();

        Sexes.Add(Sex.Male);
        Sexes.Add(Sex.Female);
    }

    public void AddRow()
    {
        var rnd = new Random(DateTime.Now.Millisecond);
        var male = rnd.Next() % 2 == 0;
        TestDataGrid.Add(new Person { Name = Guid.NewGuid().ToString(), Sex = (male ? Sex.Male : Sex.Female) });
    }
}

模特:

public class Person
{
    public string Name { get; set; }
    public Sex Sex { get; set; }
}

public class Sex
{
    public static readonly Guid MaleSexId = new Guid("9BF621E2-98FC-45FB-A4AC-4A930AD95CF7");
    public static readonly Guid FemaleSexId = new Guid("425B1B2A-B47D-4C25-A5AF-D3A0ABC95A75");

    public static Sex Male
    {
        get
        {

            return new Sex(MaleSexId);
        }
    }

    public static Sex Female
    {
        get
        {
            return new Sex(FemaleSexId);
        }
    }

    private readonly Guid _sexId;

    public Sex(Guid sexId)
    {
        _sexId = sexId;
    }

    public Guid Value
    {
        get { return _sexId; }
    }

    public override string ToString()
    {
        return _sexId == MaleSexId ? "male" : _sexId == FemaleSexId ? "female" : "unknown";
    }
}

应用屏幕:https://www.dropbox.com/s/fi1ef3z07vb09yw/2014-04-26%2013_07_22-.png

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

添加行时未选择任何项目,因为 ItemsSource SelectedValue 指的是完全不同的实例

我不知道为什么每次访问 Sex.Male Sex.Female 时总是会返回新实例。因此,当ItemsSource被设置时,添加了Male和Female的新实例,当你添加row时,返回了Male / Female的新实例,而ItemSource中没有该实例,因此没有选择任何项目。


将Sex属性设置为ComboBox中已添加的实例,如下所示:

TestDataGrid.Add(new Person { Name = Guid.NewGuid().ToString(),
                              Sex = (male ? Sexes.First() : Sexes.Last()) });

始终从男/女返回相同的实例:

public class Sex
{
    private static Sex male = new Sex(MaleSexId);
    public static Sex Male
    {
        get
        {

            return male;
        }
    }

    private static Sex female = new Sex(FemaleSexId);
    public static Sex Female
    {
        get
        {
            return female;
        }
    }

    .....
}

理想情况下, Sex 应该是Enum,不需要它有一个类。

public enum Sex
{
   Male,
   Female
}