wpf

时间:2015-09-25 22:39:57

标签: c# wpf data-binding datagrid

我有3列。一个带复选框,一个带文本列,一个带下拉。

我将整个表itemsource绑定到StepTaskViewInfo.CurrentStep.ProjectTasks.Items。 StepTaskViewInfo是我的VM中的变量,其他嵌套在其中。这很好。

只有不起作用的是FIRST列的IsReadOnly属性。假设这是一个问题,因为我的项目来源不同,并且只读属性在视图模型的嵌套级别方面不同。

For grid :
Items Source = StepTaskViewInfo -> CurrentStep -> ProjectTasks- >Items 

For read only propety of each column(which doesnt work) :

IsReadOnly="{Binding StepTaskViewInfo.AreStepsTasksReadonly


StepTaskViewInfo  => AreStepsTasksReadonly



         <DataGrid RowHeaderWidth="0" x:Name ="TaskDataGrid"  Margin="20,0,0,0" ItemsSource="{Binding StepTaskViewInfo.CurrentStep.ProjectTasks.Items}" AutoGenerateColumns="False" 
                            CanUserSortColumns="False" HorizontalAlignment="Left" CanUserAddRows="False"  SelectionChanged="TaskRowSelectionChanged" 
                                      ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Auto" 
                                      Background="White" BorderThickness ="0"
                                      ScrollViewer.CanContentScroll="True" Height="240">
                                <DataGrid.Columns>
                                    <DataGridTemplateColumn Width ="60" HeaderStyle="{StaticResource HeaderStyle}" Header="Selected" IsReadOnly="{Binding StepTaskViewInfo.AreStepsTasksReadonly,UpdateSourceTrigger=PropertyChanged }">
                                        <DataGridTemplateColumn.CellTemplate>
                                            <DataTemplate>
                                                <CheckBox  VerticalAlignment="Center" HorizontalAlignment="Center"  IsChecked="{Binding IsSelected,UpdateSourceTrigger=PropertyChanged}" 
                                                           IsEnabled="{Binding IsTaskEnabled,UpdateSourceTrigger=PropertyChanged}"  />
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellTemplate>
                                    </DataGridTemplateColumn>



       //Column 2
                                    <DataGridTextColumn HeaderStyle="{StaticResource HeaderStyle}" Header="Tasks" Width ="*" Binding="{Binding Name}" IsReadOnly="True">
                                        <DataGridTextColumn.ElementStyle>
                                            <Style TargetType="TextBlock">
                                                <Setter Property="TextWrapping" Value="Wrap" />
                                            </Style>
                                        </DataGridTextColumn.ElementStyle>
                                        <DataGridTextColumn.EditingElementStyle>
                                            <Style TargetType="TextBox">
                                                <Setter Property="TextWrapping" Value="Wrap" />
                                                <Setter Property="AcceptsReturn" Value="true" />
                                            </Style>
                                        </DataGridTextColumn.EditingElementStyle>
                                    </DataGridTextColumn>




        //Column 3


                                    <DataGridTemplateColumn  HeaderStyle="{StaticResource HeaderStyle}" Header="Status" Width ="130">
                                        <DataGridTemplateColumn.HeaderTemplate >
                                            <DataTemplate>
                                                <StackPanel Orientation="Horizontal" Width="130">
                                                    <Label Content ="Status" HorizontalAlignment="Left" Margin ="0,0,0,0"/>
                                                    <ComboBox Name ="DefaultStatusComboBox" ItemsSource="{StaticResource Status}" Width="86"  DropDownClosed="DefaultStatusComboBox_DropDownClosed"  />
                                                </StackPanel>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.HeaderTemplate>
                                        <DataGridTemplateColumn.CellTemplate>
                                            <DataTemplate>
                                                <ComboBox SelectedItem="{Binding Status, UpdateSourceTrigger=PropertyChanged}" Height ="26" VerticalAlignment="Top" IsReadOnly ="{Binding StatusIsReadOnly}" 
                                                  IsEnabled ="{Binding IsSelected}"  ItemsSource="{StaticResource Status}"/>
                                            </DataTemplate>
                                        </DataGridTemplateColumn.CellTemplate>
                                    </DataGridTemplateColumn>
                                </DataGrid.Columns>
                            </DataGrid>





view model:

public class StepTaskViewModel : INavigationAware, INotifyPropertyChanged
    {


 private readonly IProjectWorkflowService projectWorkflowService;
    private bool isVisible = true;
    private readonly IUserService userService;



        private string stageId;
        private StepTaskViewInfo stepTaskViewInfo;

        public StepTaskViewModel(IProjectWorkflowService projectWorkflowService, IUserService userService)
        {
            this.projectWorkflowService = projectWorkflowService;
            this.userService = userService;
            StepTaskViewInfo=new StepTaskViewInfo();
        }

        public StepTaskViewInfo StepTaskViewInfo
        {
            get { return stepTaskViewInfo; }
            set
            {
                stepTaskViewInfo = value; 

                OnPropertyChanged();
            }
        }

        // set current step - >load tasks - > set display names for each task --> set drop down source for current step


        public string StageId
        {
            get { return stageId; }
            set
            {
                stageId = value;
                StepTaskViewInfo.PeerReview.StageId = stageId;
                LoadData();
            }
        }




        #region navigation
        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            StageId =(string) navigationContext.Parameters["StageId"] ;
            IsVisible = true;

        }

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
            if (!IsVisible)
                return;
            IsVisible = false;
        }

        public bool IsVisible
        {
            get { return isVisible; }
            set
            {
                isVisible = value;
                OnPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = "" )
        {
            var handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

        // called when stage id changes
        public void LoadData()
        {

            var stepTaskViewInfo = projectWorkflowService.LoadProjectStepTaskInfo(StageId);

            if (StepTaskViewInfo.CurrentStep != null)
            {
                StepTaskViewInfo.CurrentStep.ProjectTasks.Items.Clear();
            }
            StepTaskViewInfo.AllTeamMembers = stepTaskViewInfo.AllTeamMembers;
            StepTaskViewInfo.ProjectSteps = stepTaskViewInfo.ProjectSteps;
            StepTaskViewInfo.PeerReview = stepTaskViewInfo.PeerReview;
            StepTaskViewInfo.AreStepsTasksReadonly = stepTaskViewInfo.AreStepsTasksReadonly;
            StepTaskViewInfo.PeerReview.Documents.Items.Add(new ActivityArtifact { FileName = string.Empty });
        }




        private string GetAliases(ObservableCollection<SelectableTeamMember> selectedStepMembers)
        {
            string aliases= selectedStepMembers.Aggregate("", (current, member) => current + (member.Alias + ";"));
            aliases= aliases.TrimEnd(';');
            return aliases;
        }
        private string GetDisplayNames(ObservableCollection<SelectableTeamMember> selectedStepMembers)
        {
            string names = selectedStepMembers.Aggregate("", (current, member) => current + (member.Name + ";"));
            names= names.TrimEnd(';');
            return names;
        }

        public void AssignResourcesToStep(ObservableCollection<SelectableTeamMember> selectedStepMembers)
        {
            StepTaskViewInfo.CurrentStep.StepTeamMembers = selectedStepMembers;
            StepTaskViewInfo.CurrentStep.Resources = GetAliases(selectedStepMembers);
            StepTaskViewInfo.CurrentStep.StepResourceDisplayName = GetDisplayNames(selectedStepMembers);


            foreach (var task in StepTaskViewInfo.CurrentStep.ProjectTasks)
            {
                task.AllTaskTeamMembers = StepTaskViewInfo.CurrentStep.StepTeamMembers;
                task.Resources = GetAliases(StepTaskViewInfo.CurrentStep.StepTeamMembers);
                task.TaskResourceDisplayName = GetDisplayNames(StepTaskViewInfo.CurrentStep.StepTeamMembers);
            }
        }

        public void AssignResourcesToTask(ObservableCollection<SelectableTeamMember> selectedTaskMembers, string taskId)
        {

            var task = StepTaskViewInfo.CurrentStep.ProjectTasks.First(st => st.Id == taskId);
            task.Resources = GetAliases(selectedTaskMembers);
            task.TaskResourceDisplayName = GetDisplayNames(selectedTaskMembers);

        }

        public void AssignTaskTips(string ttid)
        {

            string taskTip = projectWorkflowService.GetTaskTip(ttid);


            foreach (var task in StepTaskViewInfo.CurrentStep.ProjectTasks)
            {
                if (task.TemplateTaskId == ttid)
                    task.TaskTip = taskTip;
            }

        }

        #region peerreview
        public void DownloadDocument(string artifactId, string fileName)
        {
            projectWorkflowService.DownloadActivityArtifact(artifactId, fileName);
        }
        public void UploadDocument(string artifactId,string file)
        {
            projectWorkflowService.UploadActivityArtifact(StageId, artifactId, file);
            var projectDocuments = projectWorkflowService.LoadPeerReviewDocuments(StageId);
            projectDocuments.Items.Add(new ActivityArtifact { FileName = string.Empty });

            StepTaskViewInfo.PeerReview.Documents = projectDocuments;
        }

        private void GetUsers()
        {
            foreach (ProjectPeerReview t in StepTaskViewInfo.PeerReview.Reviews.Items.ToList())
            {
                if (string.IsNullOrEmpty(t.Id))
                {
                    if (!string.IsNullOrEmpty(t.Alias))
                    {
                        User current = userService.SearchAlias(t.Alias);

                        if (current == null)
                        {
                            MessageBox.Show("Could not find reviewer " + t.Alias);
                            StepTaskViewInfo.PeerReview.Reviews.Items.Remove(t);
                        }
                        else
                        {
                            t.Name = current.Name;
                        }
                    }
                }
            }
        }

        internal User[] GetSearchingUsersName(string name)
        {
            return userService.Search(name);
        }

        #endregion

        public void UpdateTaskStatus(object selectedValue)
        {
            foreach (var task in StepTaskViewInfo.CurrentStep.ProjectTasks)
            {
                task.Status = selectedValue.ToString();
            }
        }

        public void LoadTasksForCurrentStep()
        {
            StepTaskViewInfo.CurrentStep.ProjectTasks = projectWorkflowService.LoadProjectTasks( StepTaskViewInfo.CurrentStep.Id);

            StepTaskViewInfo.UpdateTaskResources();
        }

        public void SaveCurrentTasksWithStep()
        {
            if (StepTaskViewInfo.CurrentStep != null)
            {
                projectWorkflowService.SaveTasksWithStep(StageId, StepTaskViewInfo.CurrentStep, StepTaskViewInfo.CurrentStep.ProjectTasks);
            }
        }

        public bool SaveData()
        {
            if (StepTaskViewInfo.CurrentStep != null)
            {
                GetUsers();
                return projectWorkflowService.SaveStepTaskViewInfo(StepTaskViewInfo, StageId);
            }
            return true;
        }
    }



}

1 个答案:

答案 0 :(得分:1)

DataGridColumn.IsReadOnly属性将使列中的所有单元格成为ReadOnly或不是ReadOnly。 DataGridCell.IsReadOnly属性也不可分配。您要做的是,如果某些其他属性为false,则使列只读,否则列应该是可编辑的。最好使用模板列并相应地设置控件。 MSDN

例如,如果我希望用户编辑CarNumber属性值,则HasCar属性值为true,否则为true,那么如果我写:

<DataGridTextColumn Header="CarNumber" Binding="{Binding CarNumber}"  IsReadOnly="{Binding HasCar"/>

//

无论HasCar值如何,这仍然允许所有列值都可编辑。

//

如果我使用Template列并使用DataTrigger,那么我会得到所需的效果。如果HasCar属性为false,则不允许用户键入/编辑CarNumber:

<DataGridTemplateColumn Header="CarNumber" >
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>                            
                          <TextBox x:Name="TxtCarNumber" Text="{Binding CarNumber}" >
                            <TextBox.Style>
                               <Style TargetType="TextBox">
                                    <Style.Triggers>
                                       <DataTrigger Binding="{Binding HasCar}" Value="False">
                                                                <Setter Property="TextBox.Visibility" Value="Hidden"/>
                                                                <Setter Property="TextBox.Width" Value="100"/>
                                                            </DataTrigger>
                                       <DataTrigger Binding="{Binding HasCar}" Value="True">
                                                                <Setter Property="TextBox.Visibility" Value="Visible"/>
                                                                <Setter Property="TextBox.Background" Value="Red"/>
                                                            </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </TextBox.Style>
                          </TextBox>                            
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                 </DataGridTemplateColumn>

在您的代码中执行此操作,因为您希望CheckBox保持可见但未启用:

    <DataGridTemplateColumn Width ="60" HeaderStyle="{StaticResource HeaderStyle}" Header="Selected" >
        <DataGridTemplateColumn.CellTemplate>
          <DataTemplate>
            <Grid IsEnabled={Binding StepTaskViewInfo.AreStepsTasksReadonly}>
              <CheckBox  VerticalAlignment="Center" HorizontalAlignment="Center"  
IsChecked="{Binding  IsSelected,UpdateSourceTrigger=PropertyChanged}" 
                 IsEnabled="{Binding IsTaskEnabled,UpdateSourceTrigger=PropertyChanged}"  />
            </Grid>
          </DataTemplate>
       </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>