[英]How to set the binding.UpdateSourceTrigger of DataGridTextColumn in AutoGeneratingColumn event of DataGrid
[英]How to set background of a datagrid cell during AutoGeneratingColumn event depending on its value?
我仍然在操縱細胞背景,所以我問了一個新問題。
用戶“HB”寫道我可以在AutoGeneratingColumn事件期間實際設置單元格樣式 - 根據值更改DataGrid單元格顏色 。 問題是我不知道該怎么做。
我想要的:根據每個單元格的值設置不同的背景顏色 。 如果值為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>
這不起作用。 我在空單元格中有空字符串,但它們充滿了“空”,所以它應該可以工作,對嗎? 或者我做錯了什么:| ?
因此,只要單元格值是'TextBox',上面的代碼就無法工作,所以我決定找到另一種處理它的方法,可以在我的答案中找到: https : //stackoverflow.com/a/16673602 / 2296407
謝謝你試着幫我:)
我可以為你的問題提出兩種不同的解決方案:第一種是“代碼隱藏風格”(你要求但我個人認為這不是WPF中的正確方法)和更多WPF風格(更難以保存代碼) - 清潔並利用風格,觸發器和轉換器)
首先,您選擇的方法無法直接使用 - AutoGeneratingColumn事件旨在用於更改整個列的外觀,而不是逐個單元格。 因此,它可以用於,例如,根據它的顯示索引或綁定屬性將正確的樣式附加到整個列。
一般來說,第一次引發事件時,datagrid根本就沒有任何行(因此也就是單元格)。 如果您確實需要捕獲事件 - 請考慮使用DataGrid.LoadingRow事件。 你將無法讓細胞變得容易:)
那么,你做了什么:處理LoadingRow事件,獲取行(它具有Item屬性(令人驚訝:)保存你的綁定項),獲取綁定項,進行所有需要的計算,得到你需要改變的單元格和最后改變了目標細胞的風格。
這是代碼(作為項目,我使用帶有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>
我不確定你的WPF Datagrid中是否有這個屬性(Cell.Style)。 在您的情況下可能存在一些替代方案。 它適用於WinForms datagrid。
cell.Style.BackColor = System.Drawing.Color.Black;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.