我一直在构建一个测试应用程序,以查看需要的控件和 UI 布局是否可以使用 Telerik .net maui 工作。
我看过许多关于 RadDataGrid 的文档和其他关于 RadCheckBox 的文档,但是,我还没有看到任何示例来说明如何将返回的数据列之一转换为复选框。
我尝试了 2 种创建 RadDataGrid 的方法;
1)单独构建标头(这在获取后不会产生数据行)
2) 只需创建 RadDataGrid 并分配其 ItemSource(这在获取后创建列并生成数据行)
我正在使用 ObservableCollection 来容纳我所有的行数据,这就是我使用 RadDataGrid ItemSource 绑定到的数据。添加功能
当我尝试第一种方法时,我无法绑定到 ObservableCollection 中每个项目的属性,这可能是代码问题或大脑(我)问题,不确定,因为我试图遵循 Telerik 提供的示例。
我看到一个注释,如果将 RadDataGrid AutoGenerateColumns 值设置为“True”,那么 Telerik 将根据基础数据类型构建列(即,如果其中一列显示布尔数据,它会将其转换为复选框)......如果我错了,请纠正我
我也无法让该选项起作用,只是在 UI 中显示“True”或“False”。
后来查阅Telerik社区论坛发现了问题所在
只要数据项上的一个属性是布尔值,就可以使用 BooleanColumn。默认情况下,BooleanColumn 已将 CheckBox 用于编辑器。
在我讨论什么是编辑器以及显示模式和编辑模式之间的区别之前,先解决有关列生成的困惑。
设置列
如您所见,有两种方法可以获取列...为您创建它,或者您手动定义它。
自动
如果保留 AutoGenerateColumns=“True”(默认值),将自动为数据模型上的每个布尔属性创建 BooleanColumn。
手动
如果要手动定义列(我认为这就是“构建标头”的意思),则首先禁用 AutoGenerateColumns(将其设置为 false),然后需要告诉该列要绑定到哪个属性。
<span style="color:#000000"><span style="background-color:#ffffff"><span style="background-color:#ffffff"><span style="color:#000000"><span style="color:#0000ff"><<span style="color:#0000ff">telerik:RadDataGrid.Columns</span>></span>
<span style="color:#0000ff"><<span style="color:#0000ff">telerik:DataGridBooleanColumn</span> <span style="color:#ff0000">PropertyName</span>=<span style="color:#a31515">"</span><span style="color:#a31515"><span style="background-color:#fff200">MyBoolPropertyName</span></span><span style="color:#a31515">"</span> /></span>
<span style="color:#0000ff"><<span style="color:#0000ff">telerik:RadDataGrid.Columns</span>></span></span></span></span></span>
演示
例如,假设有一个 Car 类型的 ObservableCollection:
<span style="color:#000000"><span style="background-color:#ffffff"><span style="background-color:#ffffff"><span style="color:#000000"><span style="color:#0000ff">using</span> System.ComponentModel;
<span style="color:#0000ff">using</span> System.Runtime.CompilerServices;
<span style="color:#0000ff">namespace</span> <span style="color:#a31515">YourProject.DataModels</span>;
<span style="color:#0000ff">public</span> <span style="color:#0000ff">class</span> <span style="color:#a31515"><span style="background-color:#fff200">Car</span></span> : <span style="color:#a31515">BindableBase</span>
{
<span style="color:#0000ff">private</span> <span style="color:#0000ff">string</span> name;
<span style="color:#0000ff">private</span> <span style="color:#0000ff">bool</span> inStock;
<span style="color:#0000ff">public</span> <span style="color:#0000ff">string</span> Name
{
<span style="color:#0000ff">get</span> => name;
<span style="color:#0000ff">set</span> => SetProperty(<span style="color:#0000ff">ref</span> name, <span style="color:#0000ff">value</span>);
}
<span style="color:#0000ff">public</span> <span style="color:#0000ff">bool</span> InStock
{
<span style="color:#0000ff">get</span> => inStock;
<span style="color:#0000ff">set</span> => SetProperty(<span style="color:#0000ff">ref</span> inStock, <span style="color:#0000ff">value</span>);
}
}
<span style="color:#008000">// Helper class that provides PropertyChanged support through 'SetProperty'</span>
<span style="color:#0000ff">public</span> <span style="color:#0000ff">class</span> <span style="color:#a31515">BindableBase</span>: <span style="color:#a31515">INotifyPropertyChanged</span>
{
<span style="color:#0000ff">protected</span> <span style="color:#0000ff">bool</span> <span style="color:#a31515">SetProperty</span><<span style="color:#a31515">T</span>>(
<span style="color:#0000ff">ref</span> T backingStore, T <span style="color:#0000ff">value</span>,
[CallerMemberName]<span style="color:#0000ff">string</span> propertyName = <span style="color:#a31515">""</span>,
Action onChanged = <span style="color:#a31515">null</span>)
{
<span style="color:#0000ff">if</span> (EqualityComparer<T>.Default.Equals(backingStore, <span style="color:#0000ff">value</span>))
<span style="color:#0000ff">return</span> <span style="color:#a31515">false</span>;
backingStore = <span style="color:#0000ff">value</span>;
onChanged?.Invoke();
OnPropertyChanged(propertyName);
<span style="color:#0000ff">return</span> <span style="color:#a31515">true</span>;
}
<span style="color:#0000ff">public</span> <span style="color:#0000ff">event</span> PropertyChangedEventHandler PropertyChanged;
<span style="color:#0000ff">protected</span> <span style="color:#0000ff">void</span> <span style="color:#a31515">OnPropertyChanged</span>([CallerMemberName]<span style="color:#0000ff">string</span> propertyName = <span style="color:#a31515">""</span>)
{
PropertyChanged?.Invoke(<span style="color:#0000ff">this</span>, <span style="color:#0000ff">new</span> PropertyChangedEventArgs(propertyName));
}
}</span></span></span></span>
*请注意我如何使用 INotifyPropertyChanged。在使用任何类型的数据绑定时,这一点至关重要。每个属性的 setter 调用 OnPropertychanged(尽管是更干净的 BindableBase 帮助程序类)。这是让 UI 知道任何属性的值何时更改的原因。
既然你说你没有使用 MVVM,那么可以直接用几辆汽车设置 DataGrid 的 ItemsSource
<span style="color:#000000"><span style="background-color:#ffffff"><span style="background-color:#ffffff"><span style="color:#000000"><span style="color:#0000ff">using</span> System.Collections.ObjectModel;
<span style="color:#0000ff">namespace</span> <span style="color:#a31515">DataGridExample</span>;
<span style="color:#0000ff">public</span> <span style="color:#0000ff">partial</span> <span style="color:#0000ff">class</span> <span style="color:#a31515">MainPage</span> : <span style="color:#a31515">ContentPage</span>
{
<span style="color:#0000ff">private</span> <span style="color:#0000ff">readonly</span> ObservableCollection<Car> cars;
<span style="color:#0000ff">public</span> <span style="color:#a31515">MainPage</span>()
{
InitializeComponent();
cars = <span style="color:#0000ff">new</span> ObservableCollection<Car>();
dataGrid.ItemsSource = cars;
<span style="color:#008000">// Note: This can be done after setting ItemsSource because we are using an ObservableCollection.</span>
MakeSampleCars();
}
<span style="color:#0000ff">private</span> <span style="color:#0000ff">void</span> <span style="color:#a31515">MakeSampleCars</span>()
{
<span style="color:#0000ff">if</span> (cars == <span style="color:#a31515">null</span>) <span style="color:#0000ff">throw</span> <span style="color:#0000ff">new</span> NullReferenceException(<span style="color:#a31515">"cars cannot be null if you want to add a car to it"</span>);
<span style="color:#0000ff">for</span> (<span style="color:#0000ff">int</span> i = 1; i < 51; i++)
{
cars.Add(<span style="color:#0000ff">new</span> Car
{
Name = <span style="color:#a31515">$"Car {i}"</span>,
InStock = i % 3 == 0 <span style="color:#008000">//this just makes every 3rd item True</span>
});
}
}
}</span></span></span></span>
造型
您明确提到了复选框。有一点要记住,这是非常重要的。DataGrid 单元位于以下两种状态之一:
- “显示模式” - 这是呈现行并且用户滚动浏览项目的时候。
- “编辑模式” - 这是当单元格更改表单显示模式并为用户提供编辑器控件以更改该单元格所针对的任何数据类型的值(例如,文本的 Entry 、bool 的复选框等)
用户可以通过双击将单元格置于编辑模式,这仅在您看到复选框时才会出现,因为整个网格并非一直处于编辑模式。
以下是使用的所有代码在运行时的样子:
高性能和 UI 虚拟化组件这样做的原因是,如果将每个单元都保留在编辑模式下,那么性能在很多情况下几乎无法使用。这是由于编辑器组件中大量的双向绑定和复杂的布局。
但是,如果确实要显示只读复选框而不是“True”或“False”文本,则可以使用该列的自定义 CellContentTemplate 轻松执行此操作,并使用 Radcheckbox 并设置 Is
Enabled=False。
<span style="color:#000000"><span style="background-color:#ffffff"><span style="background-color:#ffffff"><span style="color:#000000"><span style="color:#0000ff"><<span style="color:#0000ff">telerik:RadDataGrid</span> <span style="color:#ff0000">x:Name</span>=<span style="color:#a31515">"dataGrid"</span> <span style="color:#ff0000">AutoGenerateColumns</span>=<span style="color:#a31515">"False"</span>></span>
<span style="color:#0000ff"><<span style="color:#0000ff">telerik:RadDataGrid.Columns</span>></span>
<span style="color:#008000"><!-- A standard textColumn for the name property --></span>
<span style="color:#0000ff"><<span style="color:#0000ff">telerik:DataGridTextColumn</span> <span style="color:#ff0000">PropertyName</span>=<span style="color:#a31515">"Name"</span> /></span>
<span style="color:#008000"><!-- A BooleanColumn for the InStock property --></span>
<span style="color:#0000ff"><<span style="color:#0000ff">telerik:DataGridBooleanColumn</span> <span style="color:#ff0000">PropertyName</span>=<span style="color:#a31515">"InStock"</span>></span>
<span style="color:#008000"><!-- If you wanted to show a checkbox while is in display mode, you can set the CellContentTemplate
Important: Make sure you have set </span><span style="color:#008000"><span style="background-color:#efe4b0">IsEnabled=False</span></span><span style="color:#008000"> so the user cannot change the value when the cell is not in edit mode
--></span>
<span style="color:#0000ff"><span style="background-color:#fff200"><</span><span style="color:#0000ff"><span style="background-color:#fff200">telerik:DataGridColumn.CellContentTemplate</span></span><span style="background-color:#fff200">></span></span>
<span style="color:#0000ff"><span style="background-color:#fff200"><</span><span style="color:#0000ff"><span style="background-color:#fff200">DataTemplate</span></span><span style="background-color:#fff200">></span></span>
<span style="color:#0000ff"><span style="background-color:#fff200"><</span><span style="color:#0000ff"><span style="background-color:#fff200">telerik:RadCheckBox</span></span> <span style="color:#ff0000"><span style="background-color:#fff200">IsChecked</span></span><span style="background-color:#fff200">=</span><span style="color:#a31515"><span style="background-color:#fff200">"{Binding InStock}"</span></span> <span style="color:#ff0000"><span style="background-color:#efe4b0">IsEnabled</span></span><span style="background-color:#efe4b0">=</span><span style="color:#a31515"><span style="background-color:#efe4b0">"False"</span></span><span style="background-color:#fff200">/></span></span>
<span style="color:#0000ff"><span style="background-color:#fff200"></</span><span style="color:#0000ff"><span style="background-color:#fff200">DataTemplate</span></span><span style="background-color:#fff200">></span></span>
<span style="color:#0000ff"><span style="background-color:#fff200"></</span><span style="color:#0000ff"><span style="background-color:#fff200">telerik:DataGridColumn.CellContentTemplate</span></span><span style="background-color:#fff200">></span></span>
<span style="color:#008000"><!-- If you wanted to use a different control for edit mode, say a Switch, you can set the CellEditTemplate--></span>
<span style="color:#008000"><!--<telerik:DataGridColumn.CellEditTemplate>
<DataTemplate>
<Switch IsToggled="{Binding InStock}" VerticalOptions="Center"/>
</DataTemplate>
</telerik:DataGridColumn.CellEditTemplate>--></span>
<span style="color:#0000ff"></<span style="color:#0000ff">telerik:DataGridBooleanColumn</span>></span>
<span style="color:#0000ff"></<span style="color:#0000ff">telerik:RadDataGrid.Columns</span>></span>
<span style="color:#0000ff"></<span style="color:#0000ff">telerik:RadDataGrid</span>></span></span></span></span></span>
现在,这是运行时的样子