Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 验证失败时设置自动生成的DataGrid列的样式_C#_Wpf_Validation_Datagrid - Fatal编程技术网

C# 验证失败时设置自动生成的DataGrid列的样式

C# 验证失败时设置自动生成的DataGrid列的样式,c#,wpf,validation,datagrid,C#,Wpf,Validation,Datagrid,我有一个DataGrid,其中填充了一个类的实例,该类公开了一个doubletype属性。此属性显示在DataGrid中。我想实现一个自定义验证,如果验证失败,我想将整个单元格涂成红色。我想我已经接近成功了,但还没有完全成功,现在我被难倒了 我的问题是我无法使条件(验证失败时)格式化工作。结果是单元格在开始时颜色正确,但是当我插入一个使faliding函数返回false的值时,我得到了通常的红色边框、白色背景单元格样式 我应该如何输入这种格式样式 XAML代码: <Window x:Cla

我有一个DataGrid,其中填充了一个类的实例,该类公开了一个
double
type属性。此属性显示在DataGrid中。我想实现一个自定义验证,如果验证失败,我想将整个单元格涂成红色。我想我已经接近成功了,但还没有完全成功,现在我被难倒了

我的问题是我无法使条件(验证失败时)格式化工作。结果是单元格在开始时颜色正确,但是当我插入一个使faliding函数返回false的值时,我得到了通常的红色边框、白色背景单元格样式

我应该如何输入这种格式样式

XAML代码:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
  <DataGrid x:Name="dg" ItemsSource="{Binding Data}">
    <DataGrid.Resources>
      <ControlTemplate x:Key="validationTemplate">
        <DockPanel>
          <AdornedElementPlaceholder/>
          <TextBlock Foreground="Red" FontSize="20">!</TextBlock>
        </DockPanel>
      </ControlTemplate>

      <Style TargetType="{x:Type TextBox}">
        <Setter Property="Background" Value="Yellow"/>
        <Setter Property="Validation.ErrorTemplate" Value="{StaticResource validationTemplate}"></Setter>
      </Style>
    </DataGrid.Resources>
  </DataGrid>
</Window>

!
代码隐藏:

public partial class MainWindow : Window
{
  ...

  private void DataGrid_AutoGeneratedColumns(object sender, EventArgs e)
  {
    foreach (DataGridTextColumn c in dg.Columns)
    {
      c.ElementStyle = (Style)dg.FindResource("s");

      for (int i = 0; i < dg.Items.Count; i++)
      {
        DataGridRow row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(i);
        if (row == null) // May be virtualized, bring into view and try again.
        {
          dg.UpdateLayout();
          dg.ScrollIntoView(dg.Items[i]);
          row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(i);
        }
        TextBlock tb = (TextBlock)c.GetCellContent(row);

        Binding binding = BindingOperations.GetBinding(tb, TextBlock.TextProperty);
        binding.ValidationRules.Clear();
        binding.ValidationRules.Add(new VR());
      }
    }
  }
}

public class VR : ValidationRule
{
  public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
  {
    ...
  }
}
公共部分类主窗口:窗口
{
...
私有void DataGrid_AutoGeneratedColumns(对象发送方,事件参数e)
{
foreach(dg.列中的DataGridTextC列)
{
c、 ElementStyle=(Style)dg.FindResource(“s”);
对于(int i=0;i

编辑:根据dev hedgehog的建议更新了XAML代码,但仍然不起作用。

您似乎使用错误模板

看看这个:

<ControlTemplate x:Key="validationTemplate">
  <DockPanel>
    <TextBlock Foreground="Red" FontSize="20">!</TextBlock>
    <AdornedElementPlaceholder/>
  </DockPanel>
</ControlTemplate>


<TextBox Name="textBox1" Width="50" FontSize="15"
         Validation.ErrorTemplate="{StaticResource validationTemplate}"
         Style="{StaticResource textBoxInError}"
         Grid.Row="1" Grid.Column="1" Margin="2">
  <TextBox.Text>
    <Binding Path="Age" Source="{StaticResource ods}"
             UpdateSourceTrigger="PropertyChanged" >
      <Binding.ValidationRules>
        <c:AgeRangeRule Min="21" Max="130"/>
      </Binding.ValidationRules>
    </Binding>
  </TextBox.Text>
</TextBox>

!
Validation.ErrorTemplate将允许您装饰AdorneDeletePlaceholder,在本例中为文本框

在示例中,我给了你一个红色!将装饰到文本框的左侧

编辑:

我更改了你的代码使它工作

<Grid>
    <DataGrid x:Name="dg" ItemsSource="{Binding Data}" PreparingCellForEdit="OnBeginningEdit">
        <DataGrid.Resources>
            <ControlTemplate x:Key="validationTemplate">
                <DockPanel>
                    <AdornedElementPlaceholder/>
                    <TextBlock Foreground="Red" FontSize="20">!</TextBlock>
                </DockPanel>
            </ControlTemplate>

            <Style TargetType="{x:Type TextBox}">
                <Setter Property="Background" Value="Yellow"/>
                <Setter Property="Validation.ErrorTemplate" Value="{StaticResource validationTemplate}"/>
            </Style>
        </DataGrid.Resources>
    </DataGrid>
</Grid>

!
这就是背后的代码

public partial class MainWindow : Window
{
    public List<D> Data { get; set; }

    public MainWindow()
    {
        Data = new List<D>();
        Random r = new Random();
        Data.Add(new D(r.NextDouble()));
        Data.Add(new D(r.NextDouble()));
        Data.Add(new D(r.NextDouble()));

        InitializeComponent();

        DataContext = this;
    }

    private void DataGrid_AutoGeneratedColumns(object sender, EventArgs e)
    {
        foreach (DataGridTextColumn c in dg.Columns)
        {
            c.EditingElementStyle = (Style)dg.FindResource("s");
        }
    }

    private void OnBeginningEdit(object sender, DataGridPreparingCellForEditEventArgs e)
    {
        TextBox tbx = (TextBox)e.EditingElement;
        Binding binding = BindingOperations.GetBinding(tbx, TextBox.TextProperty);
        binding.ValidationRules.Clear();
        binding.ValidationRules.Add(new VR());
    }
}
公共部分类主窗口:窗口
{
公共列表数据{get;set;}
公共主窗口()
{
数据=新列表();
随机r=新随机();
添加(新的D(r.NextDouble());
添加(新的D(r.NextDouble());
添加(新的D(r.NextDouble());
初始化组件();
DataContext=this;
}
私有void DataGrid_AutoGeneratedColumns(对象发送方,事件参数e)
{
foreach(dg.列中的DataGridTextC列)
{
c、 EditingElementStyle=(Style)dg.FindResource(“s”);
}
}
private void OnBeginningEdit(对象发送方,DataGridPreparingCellForeditEventTarget e)
{
TextBox tbx=(TextBox)e.EditingElement;
Binding Binding=BindingOperations.GetBinding(tbx,TextBox.TextProperty);
binding.ValidationRules.Clear();
binding.ValidationRules.Add(新的VR());
}
}
请参阅您需要使用文本框,当您在其中写入内容时,请单击鼠标以触发验证


试试看。它对我有效:)

这对我没有任何帮助。我的列是自动生成的,因此我不确定如何适应
绑定
部分,但会调用验证代码-错误格式是默认格式-任何地方都没有红色的异常标记。这可能与它是一个数据网格而不是一个文本框有关。无论如何,我也不想因为这个原因附加文本块,我只想给单元格一个自定义格式。当单元格不再有效时,你想给单元格一个自定义格式,对吗?我们可以使用ErrorTemplate,就像我刚才演示的那样,而不是使用TextBox类型,就像在我的示例中一样,您应该使用DataGridCell类型。我给你的代码只是一个例子,你不应该把它复制到你的项目中,它就是这样工作的。:)目前我正在使用TextBlock,因为这是我可以在代码隐藏(c.ElementStyle属性)中设置的。我不知道如何将样式应用于单元格,是否在AdorneDeletePlaceholder中设置样式?我已经试过了,但没有成功。因此,我无法在验证失败时对窗口应用任何自定义更改。总是红边。我甚至无法摆脱它。不,您没有在AdorneDeletePlaceholder上设置样式。您只需定义TargetType DataGridCell的样式,并将该样式放置在Window.Resource中。这就是将样式应用于单元格的方式。单元格将在生成时查找样式,并找到您将放置在Window.Resources中的样式。只要将样式的TargetType设置为DataGridCell,它就会自动发生。不过,我不希望自动应用样式,我希望在验证失败时发生。我无法在验证失败时提供自定义格式。元素的默认格式,我可以做。