我有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;
}
}
}
答案 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>