Tôi có một tình huống cần phải có điều kiện làm cho chỉ đọc đến tế bào dữ liệu wpf. Có IsReadOnly tài sản trong DataGridCell. Nhưng thật không may, tài sản đó là chỉ đọc! Có cách nào để làm điều đó?
kiến.Điều kiện làm cho chỉ đọc cho WPF DataGridCell
Trả lời
Bạn sẽ có thể sử dụng sự kiện DataGrid.BeginningEdit để kiểm tra điều kiện xem ô có thể chỉnh sửa hay không và sau đó đặt thuộc tính Hủy trên sự kiện arg nếu không.
Bạn cũng có thể sử dụng thuộc tính TemplateSelector để đặt hai DataTemplates khác nhau (một ghi và một chỉ đọc) dựa trên logic của bạn? Chỉ cần tạo một lớp kế thừa từ DataTemplateSelector và ghi đè phương thức SelectTemplate() (ở đây bạn có quyền truy cập vào datacontext).
Các giải pháp tương tự như Goblin trên, nhưng với một mẫu mã nhỏ:
Ý tưởng là để tự động chuyển đổi các CellEditingTemplate
giữa hai mẫu, một là giống như một trong CellTemplate
, khác là để chỉnh sửa . Điều này làm cho chế độ chỉnh sửa hoạt động chính xác giống như ô không chỉnh sửa mặc dù nó đang ở chế độ chỉnh sửa.
Sau đây là một số mẫu mã để làm điều này, hãy chú ý rằng phương pháp này đòi hỏi DataGridTemplateColumn
:
Thứ nhất, xác định hai mẫu cho các tế bào chỉ đọc và chỉnh sửa:
<DataGrid>
<DataGrid.Resources>
<!-- the non-editing cell -->
<DataTemplate x:Key="ReadonlyCellTemplate">
<TextBlock Text="{Binding MyCellValue}" />
</DataTemplate>
<!-- the editing cell -->
<DataTemplate x:Key="EditableCellTemplate">
<TextBox Text="{Binding MyCellValue}" />
</DataTemplate>
</DataGrid.Resources>
</DataGrid>
Sau đó xác định một mẫu dữ liệu với lớp ContentPresenter
bổ sung và sử dụng Trigger
để chuyển đổi ContentTemplate
của ContentPresenter
, do đó, hai mẫu trên có thể được chuyển động theo liên kết IsEditable
:
<DataGridTemplateColumn CellTemplate="{StaticResource ReadonlyCellTemplate}">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<!-- the additional layer of content presenter -->
<ContentPresenter x:Name="Presenter" Content="{Binding}" ContentTemplate="{StaticResource ReadonlyCellTemplate}" />
<DataTemplate.Triggers>
<!-- dynamically switch the content template by IsEditable binding -->
<DataTrigger Binding="{Binding IsEditable}" Value="True">
<Setter TargetName="Presenter" Property="ContentTemplate" Value="{StaticResource EditableCellTemplate}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
HTH
+1 cho giải pháp chỉ WPF :) –
Một giải pháp rất đơn giản cho vấn đề này là sử dụng một phong cách của DataGridCell
<DataGrid>
<DataGrid.Resources>
<Style x:Key="disabledCellStyle" TargetType="DataGridCell">
<Setter Property="IsEnabled" Value="{Binding IsEnabled}" />
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn CellStyle="{StaticResource disabledCellStyle}" />
<DataGridCheckBoxColumn CellStyle="{StaticResource disabledCellStyle}" />
<DataGridTextColumn/> /*always enabled*/
</DataGrid.Columns>
</DataGrid>
phong cách này giả định rằng có một tài sản IsEnabled trong ViewModel.
Điều này không làm cho ô chỉ đọc nhưng bị tắt. Nó gần như tương tự, ngoại trừ việc đó không thể được chọn. Giải pháp này có thể không áp dụng được trong mọi trường hợp do điều này.
IsReadOnly là kết quả boolean để kiểm tra xem ô đó có phải là readOnly hay không, đó là lý do tại sao nó là thuộc tính chỉ đọc :) – VoodooChild
Thuộc tính IsReadOnly là đọc/ghi trên DataGrid là phần tử gốc của datagrid. Thuộc tính IsReadOnly không thể đặt trong các phần tử con của DataGrid như DataGridCell vì nó không có ý nghĩa để đặt DataGridCell.IsReadOnly thành true khi DataGrid.IsReadyOnly là false – VoodooChild
@VoodooChild Lý do chính bạn không thể đặt IsReadOnly trên một DataGridCell là bởi vì chúng thoáng qua. Chúng được tạo ra và bỏ đi khi cần thiết vì DataGrid không giữ tất cả các hàng và các ô của nó trong bộ nhớ tại bất kỳ thời điểm nào. Vì vậy, không có chỗ cho bạn thậm chí thiết lập tài sản này, ngay cả khi nó đã được ghi. – Josh