绑定到数据网格行工具提示WPF中的嵌套属性

本文关键字:WPF 嵌套 属性 工具提示 数据 数据网 网格 绑定 | 更新日期: 2023-09-27 18:16:30

我不能让这个工作。我有一个视图),它包含一个数据网格,填充了一个可观察集合(MyDataCollection)的项目。MyDataCollection的每一项都有不同的属性(Name, Description,…)日志)。日志本身是一个可观察的日志项集合。每个日志项都有不同的属性(日期,人物,…)。

用MyDataCollection的项填充的数据网格每行集有一个工具提示。这样的:

<DataGrid ItemsSource="{Binding MyDataCollection}">
            <DataGrid.RowStyle>
                <Style TargetType="DataGridRow">
                    <Setter Property="ToolTip">
                        <Setter.Value>
                            <Border>
                                <Grid Margin="5" MaxWidth="400">
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="*" />
                                        ...
                                    </Grid.RowDefinitions>
                                    ...
                                    <DataGrid x:Name="LogsGrid" Grid.Row="6" ItemsSource="{Binding PlacementTarget.DataContext.Logs, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ToolTip}}">
                                        <DataGrid.Columns>
                                            <DataGridTextColumn Header="Date" 
                                                Binding="{Binding Date}" 
                                                />
                                            <DataGridTextColumn Header="Person" 
                                                Binding="{Binding Person.FullName}" 
                                                />
                                        </DataGrid.Columns>
                                    </DataGrid>
                                </Grid>
                            </Border>
                        </Setter.Value>
                    </Setter>
                </Style>
            </DataGrid.RowStyle>
        </DataGrid>

我可以看到工具提示,我可以看到工具提示中的数据网格,标题为"日期"answers"人",但网格内容是空的。看起来绑定设置不正确。有人能帮我一下吗?由于

更新1:mydatacolllecollection包含我的自定义类"Car"的对象。下面是Car的定义:

public class Car : INotifyPropertyChanged
{
    public string name;
    public string description;
    public Contact assignedTo;
    public ObservableCollection<Log> logs = new ObservableCollection<Log>();
    public string Name
    {
        get
        {
            return this.name;
        }
        set
        {
            if (this.name != value)
            {
                this.name = value;
                NotifyPropertyChanged("Name");
            }
        }
    }
    public string Description 
    {
        get
        {
            return this.description;
        }
        set
        {
            if (this.description != value)
            {
                this.description = value;
                NotifyPropertyChanged("Description");
            }
        }
    }
    public Contact AssignedTo 
    {
        get
        {
            return this.assignedTo;
        }
        set
        {
            if (this.assignedTo != value)
            {
                this.assignedTo = value;
                NotifyPropertyChanged("AssignedTo");
            }
        }
    }
    public ObservableCollection<Log> Logs
    {
        get
        {
            return this.logs;
        }
        private set //TODO : Check if this is correct
        {
            if (this.logs != value)
            {
                this.logs = value;
                NotifyPropertyChanged("Logs");
            }
        }
    }
    public Car()
    {
        // TODO: Delete this: (only here for testing)
        Contact c = new Contact();
        c.Name = "Test";
        c.LastName = "Test";
        for (int i = 0; i < 4; i++)
            AddLog(DateTime.Now, c, new TimeSpan(2, 0, 0));
    }
    public void AddLog(DateTime date, Contact person, TimeSpan time)
    {
        Log newLog = new Log(date, person, time);
        Logs.Add(newLog);
    }
    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged(string propName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }
}

我的Log Class是:

public class Log : INotifyPropertyChanged
{
    DateTime date; 
    Contact person;
    TimeSpan time;
    public DateTime Date
    {
        get
        {
            return this.date;
        }
        set
        {
            if (this.date != value)
            {
                this.date = value;
                NotifyPropertyChanged("Date");
            }
        }
    }
    public Contact Person
    {
        get
        {
            return this.person;
        }
        set
        {
            if (this.person != value)
            {
                this.person = value;
                NotifyPropertyChanged("Person");
            }
        }
    }
    public TimeSpan Time
    {
        get
        {
            return this.time;
        }
        set
        {
            if (this.time != value)
            {
                this.time = value;
                NotifyPropertyChanged("Time");
            }
        }
    }
    public Log(DateTime date, Contact person, TimeSpan time)
    {
        this.date = date;
        this.person = person;
        this.time = time;
    }
    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged(string propName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }
}

绑定到数据网格行工具提示WPF中的嵌套属性

我在你的代码中唯一能找到的对我来说不完美的是Mode=TwoWayLogsGrid.ItemsSource上的绑定。这给我抛出了一个异常,因为它告诉Binding,您希望LogsGridItemsSource的新值写回Binding源-在这种情况下,到视图模型的Logs属性。这不仅不是您想要的,而且实际上是不可能的,因为Logs有一个私有setter(而且DataGrid无论如何都不会这样做)。因此出现了例外。

UpdateSourceTrigger=PropertyChanged是另一个没有作用的参数,尽管这次没有什么害处:它告诉它何时将新的Logs集合写回Car.Logs。但是,DataGrid不能这样做。它不会为属性创建新的值。TextBox将为源属性分配新的Text值,这就是TextBox的作用。但DataGrid没有这样做。

当我去掉这两个东西时,它对我来说工作得很好:

<DataGrid x:Name="LogsGrid" Grid.Row="6" ItemsSource="{Binding Logs}">
    <!-- etc. -->

ItemsSource="{Binding PlacementTarget.DataContext.Logs, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ToolTip}}">代替ItemsSource="{Binding Logs, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">