Laden...

In einem Datagrid die Hintergrundfarbe einzelner Zeilen ändern, nachdem die Daten geprüft wurden

Letzter Beitrag vor 11 Jahren 4 Posts 1.801 Views
In einem Datagrid die Hintergrundfarbe einzelner Zeilen ändern, nachdem die Daten geprüft wurden

Ich hab folgendes Problem:

In einem DataGrid zeige ich Metadaten aus einer Azure-Datenbank an, Zu diesen Metadaten gehört außerdem auch noch ein File im BlobStorage. Grundlegend ist es erst einmal wichtig, dass die Daten aus der Datenbank angezeigt werden und das ist auch kein Problem.

Jetzt möchte ich in einem Background-Thread jeden Eintrag im BlobStorage überprüfen und falls diese Überprüfung fehl schlägt die Zeile im DataGrid farblich hervorheben.

Mein Ansatz ist bis jetzt folgender (der funktioniert aber nicht)

<DataGrid Grid.Row="1" AutoGenerateColumns="False" Name="Forms" Style="{StaticResource DataGridStyle}" IsReadOnly="True"
		  attached:DataGridMultipleSelection.SelectedItemsSource="{Binding SelectedForms}"
		  >
	<DataGrid.Columns>
		<DataGridTextColumn Header="Id" Binding="{Binding Id}" FontFamily="Consolas" />
		...
	</DataGrid.Columns>
	<DataGrid.CellStyle>
		<Style TargetType="{x:Type DataGridCell}">
			<Style.Triggers>
				<DataTrigger Binding="{Binding Converter={StaticResource CheckFileConverter}, IsAsync=True}" Value="false">
					<Setter Property="Background" Value="Red" />
				</DataTrigger>
			</Style.Triggers>
		</Style>
	</DataGrid.CellStyle>
</DataGrid>

Der CheckFileConverter sieht dann so aus:

public class CheckFileConverter : IValueConverter
{
	public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
	{
		if (value is Form)
		{
			bool result = false;

			Form formular = value as Form;
			BlobDataProvider provider = new BlobDataProvider();
			provider.OverrideConnectionString(...);
			
			// überprüfen, ob Datei überhaupt existiert
			result = provider.Exists(0, "3/" + formular.Id);
			
			...

			return result;
		}
		return false;
	}

	public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
	{
		throw new NotImplementedException();
	}
}

So. Ich hab damit gehofft, dass der Converter durch das "IsAsync" asynchron im Hintergrund ausgeführt wird, aber dem ist leider nicht so. Stattdessen wird die GUI gesperrt, bis alle Converter Aufrufe durch sind und das kann seeeehr lange dauern 😃

Wie kann ich dieses Problem lösen? Es sollte so aussehen, dass die Daten angezeigt werden und dann mit der Zeit die erkannten fehlerhaften Einträge markiert werden.
Ich sollte dazu noch erwähnen, dass ich das Objekt an dem die DataGrid-Zeilen gebunden sind nicht verändern, also keine zusätzliche Property einführen kann. Sonst würd ich das so lösen und einfach per NotifyPropertyChanged dem UI sagen, dass sich was geändert hat, wenn die Überprüfung durch ist. Aber es muss doch auch eine andere Lösung geben, oder?

Hi Mossi,

kurz gesagt kommt das Problem daher, dass du Funktionen deiner Businesslogik in die UI integrierst. Beides solltest du voneinander entkoppeln (MVVM), dann lassen sich die zeitaufwendigen Überprüfungen auch im Hintergrund durchführen!

Christian

Weeks of programming can save you hours of planning

Hallo Mossi,

dass ich das Objekt an dem die DataGrid-Zeilen gebunden sind nicht verändern, also keine zusätzliche Property einführen kann.

Das wäre aber das korrekte Vorgehen. So wie MrSparkle auch erwähnt, sollte dann die asynchrone Prüfung im ViewModel durchgeführt und anschließend die entsprechende Eigenschaft aktualisiert werden.

Das zugrunde liegende Objekt bzw. exakter die Klasse musst du nicht zwangsweise verändern, du kannst davon ableiten und in der abgeleiteten Klasse die Prüfungs-Eigenschaft anbringen.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

Danke.
Hab jetzt eine ähnliche Lösung gefunden. Hab aber nicht abgeleitet, sondern stattdessen eine Wrapper-Klasse erstellt mit den Properties "Model", das das eigentliche Objekt enthält und außerdem auch noch die Property FileCorrect, die dann asyncron gesetzt wird, wenn das Model fertig überprüft ist. Funktioniert so jetzt ganz gut.