- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我仍在与细胞背景的操纵作斗争,所以我要问一个新问题。
用户“H.B.”写道我实际上可以在 AutoGeneratingColumn 期间设置单元格样式事件 - Change DataGrid cell colour based on values .问题是我不确定该怎么做。
我想要的:根据其值为每个单元格设置不同的背景颜色。如果该值为 null
,我也希望它不是可点击的(我猜是可聚焦的)。
我拥有的/我正在尝试做的:
private void mydatagrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
foreach (Cell cell in e.Column)
{
if (cell.Value < 1)
{
cell.Background = Color.Black;
cell.isFocusable = false;
}
else
{
cell.Background = Color.Pink;
}
}
}
这只是伪代码。在列自动生成过程中是否可能发生这样的事情?如果是的话,我该如何编辑我的代码以使其有效?
我阅读了有关值转换器的内容,但我想知道它是否可以通过编程方式实现,而无需编写 XAML。
请理解,我仍然是 C#/WPF/DataGrid 的初学者。
我使用了我接受的答案。把它放进去
<Window.Resources>
<local:ValueColorConverter x:Key="colorConverter"/>
<Style x:Key="DataGridCellStyle1" TargetType="{x:Type DataGridCell}">
<Setter Property="Padding" Value="5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="True">
<Border.Background>
<MultiBinding Converter="{StaticResource colorConverter}">
<Binding RelativeSource="{RelativeSource AncestorType=DataGridCell}" Path="Content.Text"/>
<Binding RelativeSource="{RelativeSource AncestorType=DataGridCell}" Path="IsSelected"/>
</MultiBinding>
</Border.Background>
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
并为其制作了一个 MultiBinding
转换器,这样我还可以为选定的单元格设置背景颜色。
现在我只需要解决设置空单元格焦点的问题。有什么提示吗?
<Style.Triggers>
<Trigger Property="HasContent" Value="False">
<Setter Property="Focusable" Value="False"/>
</Trigger>
</Style.Triggers>
这行不通。我在空单元格中有空字符串,但它们充满了“null”所以它应该可以工作,对吧?或者我做错了什么:| ?
所以只要单元格值为“TextBox”,上面的代码就无法工作,所以我决定找到另一种方法来处理它,可以在我的答案中找到:https://stackoverflow.com/a/16673602/2296407
感谢你试图帮助我:)
最佳答案
我可以为你的问题提出两种不同的解决方案:第一种是“代码隐藏式”(你要求的但我个人认为这不是 WPF 中的正确方法)和更多 WPF 式(更棘手但保持代码隐藏干净并利用样式、触发器和转换器)
首先,您选择的方法不会直接起作用 - AutoGeneratingColumn 事件旨在用于更改整个列 的外观,而不是逐个单元格的基础。所以它可以用于,比如说,根据它的显示索引或绑定(bind)属性将正确的样式附加到整个列。
一般来说,第一次引发事件时,您的数据网格根本没有任何行(因此也没有单元格)。如果您确实需要捕获该事件 - 请考虑您的 DataGrid.LoadingRow 事件。而且您将无法轻松获得细胞 :)
那么,你要做的是:处理 LoadingRow 事件,获取行(它有 Item 属性保存(令人惊讶的是:))你的绑定(bind)项),获取绑定(bind)项,使所有需要的计算,得到你需要修改的单元格,最后修改目标单元格的样式。
这是代码(作为项目,我使用了一个示例对象,该对象具有我用于着色的 int“Value”属性)。
XAML
<DataGrid Name="mygrid" ItemsSource="{Binding Items}" AutoGenerateColumns="True" LoadingRow="DataGrid_OnLoadingRow"/>
.CS
private void DataGrid_OnLoadingRow(object sender, DataGridRowEventArgs e)
{
Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() => AlterRow(e)));
}
private void AlterRow(DataGridRowEventArgs e)
{
var cell = GetCell(mygrid, e.Row, 1);
if (cell == null) return;
var item = e.Row.Item as SampleObject;
if (item == null) return;
var value = item.Value;
if (value <= 1) cell.Background = Brushes.Red;
else if (value <= 2) cell.Background = Brushes.Yellow;
else cell.Background = Brushes.Green;
}
public static DataGridRow GetRow(DataGrid grid, int index)
{
var row = grid.ItemContainerGenerator.ContainerFromIndex(index) as DataGridRow;
if (row == null)
{
// may be virtualized, bring into view and try again
grid.ScrollIntoView(grid.Items[index]);
row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
}
return row;
}
public static T GetVisualChild<T>(Visual parent) where T : Visual
{
T child = default(T);
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
var v = (Visual)VisualTreeHelper.GetChild(parent, i);
child = v as T ?? GetVisualChild<T>(v);
if (child != null)
{
break;
}
}
return child;
}
public static DataGridCell GetCell(DataGrid host, DataGridRow row, int columnIndex)
{
if (row == null) return null;
var presenter = GetVisualChild<DataGridCellsPresenter>(row);
if (presenter == null) return null;
// try to get the cell but it may possibly be virtualized
var cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex);
if (cell == null)
{
// now try to bring into view and retreive the cell
host.ScrollIntoView(row, host.Columns[columnIndex]);
cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex);
}
return cell;
}
此解决方案仅将代码隐藏用于值到颜色的转换(假设着色逻辑比相等比较更复杂 - 在这种情况下,您可以使用触发器并且不要弄乱转换器)。
您所做的:使用包含数据触发器的样式设置 DataGrid.CellStyle 属性,它检查单元格是否在所需的列中(基于它的 DisplayIndex),如果是 - 通过转换器应用背景。
XAML
<DataGrid Name="mygrid" ItemsSource="{Binding Items}" AutoGenerateColumns="True">
<DataGrid.Resources>
<local:ValueColorConverter x:Key="colorconverter"/>
</DataGrid.Resources>
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Column.DisplayIndex}" Value="1">
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Path=Content.Text, Converter={StaticResource colorconverter}}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
</DataGrid>
.CS
public class ValueColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var str = value as string;
if (str == null) return null;
int intValue;
if (!int.TryParse(str, out intValue)) return null;
if (intValue <= 1) return Brushes.Red;
else if (intValue <= 2) return Brushes.Yellow;
else return Brushes.Green;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
UPD:如果您需要为整个数据网格着色,XAML 更容易(无需使用触发器)。使用以下 CellStyle:
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Path=Content.Text, Converter={StaticResource colorconverter}}"/>
</Style>
</DataGrid.CellStyle>
关于c# - 如何根据其值在 AutoGeneratingColumn 事件期间设置数据网格单元格的背景?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16645688/
我已经尝试在我的 CSS 中添加一个元素来删除每三个 div 的 margin-right。不过,似乎只是出于某种原因影响了第 3 次和第 7 次。需要它在第 3、6、9 等日工作... CSS .s
如何使 div/input 闪烁或“脉冲”?例如,假设表单字段输入了无效值? 最佳答案 使用 CSS3 类似 on this page ,您可以将脉冲效果添加到名为 error 的类中: @-webk
我目前正在尝试构建一个简单的 wireframe来自 lattice 的情节包,但由沿 y 轴的数百个点组成。这导致绘图被线框网格淹没,您看到的只是一个黑色块。我知道我可以用 col=FALSE 完全
在知道 parent>div CSS 选择器在 IE 中无法识别后,我重新编码我的 CSS 样式,例如: div#bodyMain div#paneLeft>div{/*styles here*/}
我有两个 div,一个在另一个里面。当我将鼠标悬停 到最外面的那个时,我想改变它的颜色,没问题。但是,当我将鼠标悬停 到内部时,我只想更改它的颜色。这可能吗?换句话说,当 将鼠标悬停到内部 div 上
我需要展示这样的东西 有人可以帮忙吗?我可以实现以下输出 我正在使用以下代码:: GridView.builder( scrollDirection: Axis.vertical,
当 Bottom Sheet 像 Android 键盘一样打开时,是否有任何方法可以手动上推布局( ScrollView 或回收器 View 或整个 Activity )?或者你可以说我想以 Bott
我有以下代码,用于使用纯 HTML 和 CSS 显示翻转。当您将鼠标悬停在文本上时,它会更改左右图像。 在我测试的所有浏览器中都运行良好,Safari 4 除外。据我收集的信息,Safari 4 支持
我构建了某种 CMS,但在使用 TinyMCE 和 Bootstrap 时遇到了一些问题。 我有一个页面,其中概述了一个 div,如果用户单击该 div,他们可以从模态中选择图像。该图像被插入到一个
出于某种原因,当我设置一个过渡时,当我的鼠标悬停在一个元素上时,背景会改变颜色,它只适用于一个元素,但它们都共享同一个类?任何帮助我的 CSS .outer_ad { position:rel
好吧,这真的很愚蠢。我不知道 Android Studio 中的调试监视框架发生了什么。我有 1.5.1 的工作室。 是否有一些来自 intellij 的 secret 知识来展示它。 最佳答案 与以
我有这个标记: some code > 我正在尝试获取此布局: 注意:上一个和下一个按钮靠近#player 我正在尝试这样: .nextBtn{
网站:http://avuedesigns.com/index 首页有 6 个菜单项。我希望每件元素在您经过时都有自己的颜色。 这是当您将鼠标悬停在 div 上时将所有内容更改为白色的行 li#hom
我需要在 index.php 文件中显示它,但没有任何效果。我所有的文章都没有正确定位。我将其用作代码: 最佳答案 您可以首先检查您
我是一名优秀的程序员,十分优秀!