【问题标题】:WPF DataGrid DataGridTemplateColumnWPF DataGrid DataGridTemplateColumn
【发布时间】:2014-06-12 04:11:30
【问题描述】:

我正在尝试在数据网格上显示一个人的姓名和性别。用户应该能够输入姓名并从组合框中选择性别。我希望组合框一直可见,所以我使用 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";
    }
}

还有一屏app:https://www.dropbox.com/s/fi1ef3z07vb09yw/2014-04-26%2013_07_22-.png

任何帮助将不胜感激。

【问题讨论】:

    标签: wpf xaml binding datagrid combobox


    【解决方案1】:

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

    我不知道您为什么每次访问 Sex.MaleSex.Female 时总是返回新实例。因此,当 ItemsSource 设置时,会添加新的 Male 和 Female 实例,当您添加行时,会返回新的 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
    }
    

    【讨论】:

    • 这是一个非常愚蠢的错误。我认为静态 getter 每次都会返回相同的实例。所以谢谢你纠正我。 Sex 类只是找出数据网格绑定的简单示例。在实际应用中,我使用的是更复杂的类。
    猜你喜欢
    • 2013-06-30
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    • 2013-01-28
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多