Есть ли способ изменить встроенные строки с BackgroundWorker?Изменить TextBlock.Inlines from Backgroundworker
Я попытался следующие:
private void test()
{
var rows = GetDataGridRows(dgVarConfig);
foreach (DataGridRow r in rows)
{
TextBlock tb = cMatchEx.GetCellContent(r) as TextBlock;
if (!syntaxWorker.IsBusy)
syntaxWorker.RunWorkerAsync(new KeyValuePair<TextBlock, String>(tb, tb.Text));
}
}
private void syntaxWorker_DoWork(object sender, DoWorkEventArgs e)
{
if (e.Argument == null)
Thread.Sleep(100);
else
{
KeyValuePair<TextBlock, String> kvp = (KeyValuePair<TextBlock, String>)e.Argument;
e.Result = new KeyValuePair<TextBlock, List<Run>>(kvp.Key, Syntax.Highlight(kvp.Value));
}
}
private void syntaxWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Result != null)
{
KeyValuePair<TextBlock, List<Run>> kvp = (KeyValuePair<TextBlock, List<Run>>)e.Result;
TextBlock tb = kvp.Key;
tb.Text = "";
kvp.Value.ForEach(x => tb.Inlines.Add(x));
}
}
и класс синтаксиса:
public static class Syntax
{
static Regex subFormula = new Regex(@"\w+\(\)");
static Regex sapFormula = new Regex(@"\w+\(([^)]+)\)");
static Regex strings = new Regex(@"\'[^']+\'");
static Regex numerals = new Regex(@"\b[0-9\.]+\b");
static Regex characteristic = new Regex(@"(?:)?\w+(?:)?");
static Regex andOr = new Regex(@"(and)|(AND)|(or)|(OR)");
static Regex not = new Regex(@"(not)|(NOT)");
private static Brush[] colorArray;
public static List<Run> Highlight(String input)
{
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.Orange, strings.Matches(input));
assignColor(Brushes.DeepPink, subFormula.Matches(input));
assignColor(Brushes.Green, sapFormula.Matches(input));
assignColor(Brushes.Green, not.Matches(input));
int index = 0;
List<Run> runList = new List<Run>();
foreach (Char character in input)
{
runList.Add(new Run(character.ToString()) { Foreground = colorArray[index] });
index++;
}
colorArray = null;
return runList;
}
public static void Check(TextBlock textBlock)
{
}
private static 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;
}
}
}
}
Я непрестанно получаю эту ошибку: The calling thread cannot access this object because a different thread owns it.
Я пробовал много разных вещей: вернуть runList с прогрессом изменил статический класс синтаксиса на нормальный класс .. но ничего не работало, его всегда была одна и та же ошибка.
Я также попытался вызвать его из BackgroundWorker .. это означает, что вызов
List<Run> runList = Syntax.Highlight(kvp.Value);
this.Dispatcher.Invoke((Action)(() =>
{
runList.ForEach(x => publicRunList.Add(x));
}));
Кто-нибудь знает эту проблему?
Где именно вы получите эту ошибку? – Domysee
RunWorkerCompleted, где я хочу добавить встроенные строки –
Вы пробовали синхронизацию? – Karolis