C#,WPF-数据网格单元格中的多种颜色(syntaxhighlighting)

C#,WPF-数据网格单元格中的多种颜色(syntaxhighlighting),c#,wpf,xaml,datagrid,converter,C#,Wpf,Xaml,Datagrid,Converter,我为我的datagrid开发了一些语法突出显示和语法检查: public class HighlightConverter : IMultiValueConverter { public static Dictionary<String, SyntaxResult> calcFormulaCache; public static Dictionary<String, SyntaxResult> matchExpressionCache; publ

我为我的datagrid开发了一些语法突出显示和语法检查:

public class HighlightConverter : IMultiValueConverter
{
    public static Dictionary<String, SyntaxResult> calcFormulaCache;
    public static Dictionary<String, SyntaxResult> matchExpressionCache;

    public HighlightConverter()
    {
        calcFormulaCache = new Dictionary<string, SyntaxResult>();
        matchExpressionCache = new Dictionary<string, SyntaxResult>();
    }

    ClientSettings clientSettings = ClientSettings.getInstance();

    Brush[] colorArray;

    Regex subFormula = new Regex(@"\w+\(\)");
    Regex sapFormula = new Regex(@"\w+\(([^)]+)\)");
    Regex strings = new Regex(@"\'[^']+\'");
    Regex numerals = new Regex(@"\b[0-9\.]+\b");
    Regex characteristic = new Regex(@"(?:)?\w+(?:)?");
    Regex andOr = new Regex(@"( and )|( AND )|( or )|( OR )");
    Regex not = new Regex(@"(not )|(NOT )");


    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {

        if (!clientSettings.SyntaxCheck && !clientSettings.SyntaxHighlighting || String.IsNullOrEmpty(values[0] as String))
            return values[0];

        SAPConnector sapConnector = SAPConnector.getInstance();
        TextBlock textBlock = new TextBlock();
        string input = values[0] as String;

        if (!String.IsNullOrEmpty(input))
        {
            if (clientSettings.SyntaxHighlighting)
            {
                    colorArray = new Brush[input.Length];

                    for (int i = 0; i < input.Length; i++)
                        colorArray[i] = Brushes.Black;

                    //Reihenfolge beibehalten!!
                    assignColor(Brushes.Blue, characteristic.Matches(input));
                    assignColor(Brushes.Black, andOr.Matches(input));
                    assignColor(Brushes.Black, numerals.Matches(input));
                    assignColor(Brushes.Brown, strings.Matches(input));
                    assignColor(Brushes.DeepPink, subFormula.Matches(input));
                    assignColor(Brushes.Green, sapFormula.Matches(input));
                    assignColor(Brushes.Green, not.Matches(input));

                    int index = 0;
                    foreach (Char character in input)
                    {
                        textBlock.Inlines.Add(new Run(character.ToString()) { Foreground = colorArray[index] });
                        index++;
                    }

                    colorArray = null;
            }
            else
            {
                colorArray = null;
                textBlock.Text = input;
            }

            if (clientSettings.SyntaxCheck)
            {
                Pen pen = new Pen(Brushes.Red, 3);
                TextDecoration textDec = new TextDecoration(TextDecorationLocation.Underline, pen, 4, TextDecorationUnit.Pixel, TextDecorationUnit.FontRecommended);

                if (!String.IsNullOrEmpty((String)parameter))
                {
                    String para = (String)parameter;
                    SyntaxResult syntaxResult = null;

                    switch (para)
                    {
                        case "VARIANT":
                            if (para == "VARIANT")
                            {
                                if (characteristic.IsMatch(input) || subFormula.IsMatch(input))
                                {
                                    if (andOr.IsMatch(input) || numerals.IsMatch(input) || strings.IsMatch(input) || sapFormula.IsMatch(input) || not.IsMatch(input))
                                    {
                                        textBlock.TextDecorations.Add(textDec);
                                        textBlock.ToolTip = "Hier darf nur ein Merkmal oder eine Subformel stehen";
                                    }
                                }
                            }
                            break;
                        case "CALCFORMULA":
                            try
                            {
                                if (!calcFormulaCache.ContainsKey(input))
                                    calcFormulaCache.Add(input, sapConnector.variantConfigurationTestDAO.vcCalculateFormula3(input, true));

                                syntaxResult = calcFormulaCache[input];
                            }
                            catch (Exception ex)
                            {
                                textBlock.TextDecorations.Add(textDec);
                                textBlock.ToolTip = "Syntaxüberprüfung fehlgeschlagen: " + ex.Message;
                                Logger.getInstance().writeLogEntry(Logger.LogLevel.ERROR, String.Format("Syntaxcheckfehler: Die Kalkulationsformel '{0}' konnte nicht überprüft werden --> {1}", input, ex.Message), ex.StackTrace);
                            }
                            break;
                        case "MATCHEXPRESSION":
                            try
                            {
                                if (!matchExpressionCache.ContainsKey(input))
                                    matchExpressionCache.Add(input, sapConnector.variantConfigurationTestDAO.vcEvalMatchEx(input, true));

                                syntaxResult = matchExpressionCache[input];
                            }
                            catch (Exception ex)
                            {
                                textBlock.TextDecorations.Add(textDec);
                                textBlock.ToolTip = "Syntaxüberprüfung fehlgeschlagen: " + ex.Message;
                                Logger.getInstance().writeLogEntry(Logger.LogLevel.ERROR, String.Format("Syntaxcheckfehler: Die Ausdrucksformel '{0}' konnte nicht überprüft werden --> {1}", input, ex.Message), ex.StackTrace);
                            }

                            break;
                        default:
                            break;
                    }


                    if (syntaxResult != null)
                    {
                        if (syntaxResult.syntax > 0)
                        {
                            textBlock.TextDecorations.Add(textDec);

                            if (syntaxResult.errors.Count == 0)
                                textBlock.ToolTip = "Allgemeiner Syntaxfehler";
                            else
                            {
                                List<String> groupedErrors = new List<String>();
                                foreach (String error in syntaxResult.errors)
                                {
                                    if (groupedErrors.FirstOrDefault(x => x == error) == null)
                                        groupedErrors.Add(error);
                                }

                                textBlock.ToolTip = String.Join(Environment.NewLine, groupedErrors);
                            }
                        }
                    }
                }

                if (values.Count() == 2)
                {
                    string input2 = values[1] as String;

                    if (String.IsNullOrEmpty(input2))
                    {
                        textBlock.TextDecorations.Add(textDec);
                        textBlock.ToolTip = "Es müssen Variante und Kalkulationsformel gefüllt sein";
                    }
                }
            }
        }

        ToolTipService.SetShowDuration(textBlock, 999999);
        return textBlock;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }


    private void assignColor(Brush brush, MatchCollection matchCollection)
    {
        foreach (Match match in matchCollection)
        {
            int start = match.Index;
            int end = start + match.Length;

            for (int i = start; i < end; i++)
            {
                colorArray[i] = brush;
            }
        }
    }

}
<DataGridTextColumn Binding="{Binding TopLevelGroup, IsAsync=False}" x:Name="cTopLevelGroup" MinWidth="150" Visibility="Visible">
                <DataGridTextColumn.HeaderStyle>
                    <Style TargetType="{x:Type DataGridColumnHeader}">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="auto"/>
                                            <ColumnDefinition Width="*"/>
                                            <ColumnDefinition Width="auto"/>
                                            <ColumnDefinition Width="auto"/>
                                            <ColumnDefinition Width="auto"/>
                                        </Grid.ColumnDefinitions>

                                        <Label Grid.Column="1" Padding="5 0" Content="Gruppe"  FontWeight="Bold" VerticalAlignment="Center" Cursor="Hand" Foreground="White"/>
                                        <TextBox x:Name="txtTopGroupFilter" Margin="0 5" Grid.Column="2" Width="150" Visibility="Collapsed"/>
                                        <Button Grid.Column="3" Margin="5 0" x:Name="btnFilterTopGroup" Style="{StaticResource MyButton}" Width="16" Height="16" VerticalAlignment="Center" HorizontalAlignment="Right" Click="btnFilterTopGroup_Click">
                                            <Button.Background>
                                                <ImageBrush ImageSource="Resources/filter.png"/>
                                            </Button.Background>
                                        </Button>

                                        <Path x:Name="SortArrow"
                                        Grid.Column="0"
                                        HorizontalAlignment="Right" VerticalAlignment="Center"                                           
                                        Width="8" Height="6" Margin="2,0,5,0"
                                        Stretch="Fill" Opacity="0.5" Fill="White"
                                        RenderTransformOrigin="0.5,0.4"
                                        Visibility="Collapsed"
                                        Data="M0,0 L1,0 0.5,1 z" />

                                        <Thumb x:Name="PART_RightHeaderGripper" Grid.Column="3"
                    HorizontalAlignment="Right"
                    Width="2" BorderThickness="1"
                    BorderBrush="{Binding VerticalGridLinesBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"
                    Cursor="SizeWE"/>

                                    </Grid>

                                    <ControlTemplate.Triggers>
                                        <Trigger Property="SortDirection" Value="Ascending">
                                            <Setter TargetName="SortArrow" Property="Visibility" Value="Visible" />
                                            <Setter TargetName="SortArrow" Property="RenderTransform">
                                                <Setter.Value>
                                                    <RotateTransform Angle="180" />
                                                </Setter.Value>
                                            </Setter>
                                        </Trigger>
                                        <Trigger Property="SortDirection" Value="Descending">
                                            <Setter TargetName="SortArrow" Property="Visibility" Value="Visible" />
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>


                            </Setter.Value>
                        </Setter>
                    </Style>
                </DataGridTextColumn.HeaderStyle>

            </DataGridTextColumn>
公共类HighlightConverter:IMultiValueConverter
{
公共静态字典calcFormulaCache;
公共静态字典匹配表达式缓存;
公共高光转换器()
{
calcFormulaCache=新字典();
matchExpressionCache=新字典();
}
ClientSettings ClientSettings=ClientSettings.getInstance();
刷子阵列;
正则表达式子形式=新正则表达式(@“\w+\(\)”);
正则表达式sapFormula=新正则表达式(@“\w+\([^)]+)\”;
正则表达式字符串=新正则表达式(@“\”[^']+\”);
正则表达式数字=新正则表达式(@“\b[0-9\.]+\b”);
正则表达式特征=新正则表达式(@“(?:)?\w+(?:)?”;
正则表达式和或=新正则表达式(@“(and)|(and)|(and)|(or)|(or)”);
正则表达式not=新正则表达式(@“(not)|(not)”;
公共对象转换(对象[]值,类型targetType,对象参数,CultureInfo区域性)
{
如果(!clientSettings.SyntaxCheck&&!clientSettings.SyntaxHighlighting | | | String.IsNullOrEmpty(值[0]为字符串))
返回值[0];
SAPConnector SAPConnector=SAPConnector.getInstance();
TextBlock TextBlock=新的TextBlock();
字符串输入=值[0]作为字符串;
如果(!String.IsNullOrEmpty(输入))
{
if(clientSettings.SyntaxHighlighting)
{
colorArray=新画笔[input.Length];
for(int i=0;i{1}”,输入,ex.Message),ex.StackTrace);
}
打破
案例“匹配表达式”:
尝试
{
如果(!matchExpressionCache.ContainsKey(输入))
matchExpressionCache.Add(输入,sapConnector.VariantConfiguration TestDao.vcEvalMatchEx(输入,true));
syntaxResult=matchExpressionCache[input];
}
捕获(例外情况除外)
{
textBlock.textdecuments.Add(textDec);
textBlock.ToolTip=“Syntaxüberprüfung fehlgeschlagen:”+例如消息;
Logger.getInstance().writeLogEntry(Logger.LogLevel.ERROR,String.Format(“Syntaxcheckfehler:Die Ausdrucksformel'{0}'konnte nichtüberprüft werden-->{1}”,输入,ex.Message),ex.StackTrace);
}
打破
违约:
打破
}
if(syntaxResult)
<DataGrid x:Name="dgVarConfig"
              ItemsSource="{Binding VarConfigList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
              SelectedItem="{Binding SelectedVarConfig, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
              Margin="10,56,557,80"
              AutoGenerateColumns="False"
              CanUserDeleteRows="False"
              CanUserResizeRows="False"
              HeadersVisibility="Column"
              CanUserAddRows="False"
              HorizontalScrollBarVisibility="Auto"
              PreviewKeyDown="dgVarConfig_PreviewKeyDown"
              BeginningEdit="dgVarConfig_BeginningEdit"
              CellEditEnding="dgVarConfig_CellEditEnding"
              SelectionChanged="dgVarConfig_SelectionChanged"

              VirtualizingPanel.IsVirtualizing="true"
              EnableRowVirtualization="True"
              EnableColumnVirtualization="false"
              VirtualizingPanel.VirtualizationMode="Recycling"
              VirtualizingPanel.IsVirtualizingWhenGrouping="True"
              ScrollViewer.CanContentScroll="False"
             >