Laden...

SetBinding (Code Behind) funktioniert nicht, TextBlock.Text wird dabei gelöscht

Letzter Beitrag vor 13 Tagen 7 Posts 394 Views
SetBinding (Code Behind) funktioniert nicht, TextBlock.Text wird dabei gelöscht

Hallo ihr Lieben,

ich habe ein kleines Testprojekt geschrieben um mein Problem einfach zu veranschaulichen.

Folgender Ablauf:

  1. Ich habe im XAML einen TextBlock mit einem Binding zu einer RelativSource.
  2. Im CodeBehind werden dann die Inlines des TextBlocks mit Highlighting Informationen erweitet
  3. Durch DataGrid mit VirtualizingStackPanel.VirtualizationMode="Recycling" ist im Event DataGrid.OnLoadingRow aber auch im Event DataGridRow.Loaded das Ergebnis von GetBindingExpression(TextBlock.TextProperty) null
  4. Nun habe ich versucht, das Binding neu zu setzen
  5. Doch das führt dazu, dass der Text im TextBlock mit dem Default-Wert ("") ersetzt wird, statt anhand dem Binding den richtigen Text heranzuziehen.

Ich hoffe ihr könnt mir helfen, wie ich es schaffen kann, dass der Text nach dem Setzen des Bindings vorhanden ist.

XAML

<StackPanelTag="{Binding Path=MissionName, Converter={StaticResource DebugConverter}}">
    <TextBlock
        Text="{Binding Path=Tag, RelativeSource={RelativeSource AncestorType=StackPanel}" />
</StackPanel>

Code Behind

// Daten für Binding merken

var exp = txtBlock.GetBindingExpression(TextBlock.TextProperty);
txtBlock.Tag = new Tuple<RelativeSource, PropertyPath>(exp.ParentBinding.RelativeSource, exp.ParentBinding.Path)


var inlines = new List<Inline>();
inlines.Add(new Run(text.Substring(0, 1)));
inlines.Add(new Run(text.Substring(1, 2))
        {
            Background = filterData.SelectionColor,
            Foreground = filterData.ForegroundColor
        });
inlines.Add(new Run(text.Substring(3, 1)));

txtBlock.Inlines.Clear();
txtBlock.Inlines.AddRange(inlines);

Im Event

var tagData = (Tuple<RelativeSource, PropertyPath>) txtBlock.Tag;

var binding = new Binding { RelativeSource = tagData.Item1, Path = tagData.Item2};
txtBlock.SetBinding(TextBlock.TextProperty, binding);	// <- txtBlock.Text ist jetzt ""


// Dieser Aufruf sagt jetzt, IsDirty="true" & Status="Unattached"
var exp = txtBlock.GetBindingExpression(TextBlock.TextProperty);

Ich hoffe ihr habe eine Idee.

Ich weiß, es entspricht nicht MVVM, aber aktuell versuche ich das so um Laufen zu bringen, muss ja irgendwie gehen 😃

Vielen Dank euch allen

Lieben Gruß

Hallo AnnaBauer21

Ich kann aus dem was ich hier sehe, nur raten. Versuch doch mal bei

new Binding { RelativeSource = tagData.Item1, Path = tagData.Item2};

einen BindingMode mit anzugeben.

Gruss
Alf

Hallo Alf,

tatsächlich klappt es, wenn ich im XAML den BindingMode TwoWay verwende.

Es scheint, als würde bei TwoWay die Bindinginformation nicht verloren gehen, bei OneWay aber schon.

Aber ich suche auch eine Lösung dafür, wenn OneWay verwendet wird, dass es durch das neue Setzen des Bindings den Text nicht verwirft sondern entsprechend dem Binding, den Text aktualisert.

Lieben Gruß

Hat die Blume einen Knick, war der Schmetterling zu dick.

Hast du dir schon mal UI.SyntaxBox angeschaut?

Ja, das ist eine TextBox aber es geht eher um das Prinzip, wie die das da machen. Da wird auf jeden Fall das Binding überhaupt nicht gestört.

Hat die Blume einen Knick, war der Schmetterling zu dick.

Hallo,
Ich habe eine Lösung gefunden.

Ich befinde mich im Event „LoadingRow“ des DataGrids.

Das Binding wird neu gesetzt, aber da die Row gerade beim "Laden" ist, sehe ich keine Änderungen im Text.

Nachdem ich das Binding gesetzt habe, rufe ich nun eine Methode mit „BeginInvoke DispatcherPriority.Loaded“ auf, die das Highlighting durchführen soll.

In dieser Methode ist die Row dann geladen und die Textblöcke beinhalten die richtigen Texte.

Danke für den Tipp, werde ich mir mal ansehen 😃