当itemsource是一个对象集合时,如何在组合框中设置SelectedvaluePath?

时间:2016-05-21 13:05:05

标签: c# wpf xaml combobox datagrid

我在WPF中的Datagrid中有一个Combobox,而我的DataSrid到Datagrid是一个Class的Observable集合。 Class包含另一个包含各种属性的类的列表。

这是我的Observable Collections的样子

public ObservableCollection<TimeLog> Logs
    {
        get
        {
            return _logs;
        }
        set
        {
            _logs = value;
        }
    }

这是Observable Collection背后使用的类

public class TimeLog
    {
        private List<Projects> _project;
        public List<Projects> Project
        {
            get
            {
                return _project;
            }
            set
            {
                _project = value;
            }
        }

        private string _taskName;
        public string TaskName
        {
            get
            {
                return _taskName;
            }
            set
            {
                _taskName = value;
            }
        }

        private DateTime _dateSelected;
        public DateTime DateSelected
        {
            get
            {
                return _dateSelected;
            }
            set
            {
                _dateSelected = value;
            }
        }

        private double _hoursSpent;
        public double HoursSpent
        {
            get
            {
                return _hoursSpent;
            }
            set
            {
                _hoursSpent = value;
            }
        }

        /// <summary>
        /// Empty Constructor
        /// </summary>
        public TimeLog()
        {
            _project = new List<Projects>() { new Projects() };
            _dateSelected = DateTime.Today;
            _taskName = string.Empty;
            _hoursSpent = 0.0;
        }
    }

这是我的项目类..

    public class Projects
    {
       private string _projectName;

       public string ProjectName
       {
          get
          {
             return _projectName;
          }
          set
          {
              _projectName = value;
          }
       }

      private DateTime _startDate;
      public DateTime Startdate
      {
        get
        {
            return _startDate;
        }
        set
        {
            _startDate = value;
        }
      }


      private DateTime _enddate;
      public DateTime EndDate
      {
        get
        {
            return _enddate;
        }
        set
        {
            _enddate = value;
        }
      }

      /// <summary>
      /// Could be optional property. But useful for efficient time logging
      /// </summary>
      private double _percentageAllocation;
      public double PercentageAllocation
      {
        get
        {
            return _percentageAllocation;
        }
        set
        {
            _percentageAllocation = value;
        }
      }

      public Projects()
      {
        _projectName = string.Empty;
        _startDate = DateTime.Today;
        _enddate = DateTime.Today;
        _percentageAllocation = 0.0;
      }
}

这就是我的XAML的样子。

 <DataGrid  ItemsSource="{Binding Logs}" AutoGenerateColumns="False" CanUserAddRows="False">
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Project Name">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox Name="cbProjects" ItemsSource="{Binding Project}" SelectedItem="{Binding DataContext.ComboSelectedItem,Converter={StaticResource covert},UpdateSourceTrigger=PropertyChanged}" >
                            </ComboBox>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn Header="Allocation">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Name="tbAllocation" Text="{Binding DataContext.ComboSelectedItem,Converter={StaticResource covert},UpdateSourceTrigger=PropertyChanged}"></TextBlock>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTextColumn Binding="{Binding TaskName}" Header="Task Name"></DataGridTextColumn>
                <DataGridTextColumn Binding="{Binding HoursSpent}" Header="Hours Spent"></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>

放置在datagrid中的Combobox需要与SelectedvaluePath属性绑定到Projects类的AllocationPercentage属性。我已经尝试了很多次但是运气不好。有人可以指导在这些场景中需要做什么,如果我在这个实现中做了任何错误,请帮助纠正我。

我需要完成的是,无论何时我选择Combobox的值(因为Combobox属于Projects类型),我需要在下面的文本块中绑定选定的值(最好是AllocationPercentage)。

1 个答案:

答案 0 :(得分:1)

您希望在值更改但您尚未实现INotifyPropertyChanged接口时更新网格。您有一个ObservableCollection,但您的TimeLog类没有可观察的属性。

public class TimeLog : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    // extra property for the selected project
    private Projects _selectedProjects 
    public Projects SelectedProjects
    {
        get 
        {
            if (_selectedProjects == null && _project.Any())
            {
                _selectedProjects = _project.First();
            }
            return _selectedProjects;
        };
        set
        {
             _selectedProjects = value;
             OnPropertyChanged("_SelectedProjects");
        };
    }
    List<Projects> _project;

    // Ommited the rest

    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

因为这是我的首选方式,你可以像这样重新排列你的WPF:

            <DataGridTemplateColumn Header="Project Name">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox Name="cbProjects" DataContext="{Binding}" ItemsSource="{Binding Project}" SelectedItem="{Binding Projects}" SelectionChanged="OnMyComboBoxChanged" >
                        </ComboBox>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn Header="Allocation">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Name="tbAllocation" DataContext="{Binding SelectedProjects}" Text="{Binding AllocationPercentage"></TextBlock>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

在c#中

private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    var cbb = (ComboBox)sender;
    var projects= (Projects)cbb.SelectedItem;
    var timeLog = (TimeLog)cbb.DataContext;

    timeLog.SelectedProjects = projects;
}

我认为这是你想要的方向。 这是从头顶写的,很抱歉任何编译错误:)