Laden...

Mehrere Parameter mit Command übergeben beim Hyperlink

Erstellt von habib vor 3 Jahren Letzter Beitrag vor 3 Jahren 643 Views
H
habib Themenstarter:in
24 Beiträge seit 2020
vor 3 Jahren
Mehrere Parameter mit Command übergeben beim Hyperlink

Ich würde gern dem Command noch zusätzlich den Label Content mitgeben, aber wie?
Multibinding scheint mit Hyperlink nicht gehen.


       <StackPanel Grid.Column="0" Grid.Row="4">
            <Label Content="TeamViewer-ID" />
            <TextBlock>
                <Hyperlink Command="{Binding CopyCommand}" CommandParameter="{Binding TeammViewerText}">
                    <TextBlock Text="{Binding TeammViewerText}" />
                </Hyperlink>
            </TextBlock>
        </StackPanel>

Besten Dank

2.079 Beiträge seit 2012
vor 3 Jahren

Kurz: Geht nicht - zumindest nicht ohne Tricks.

Du kannst dir sowas selber bauen, indem Du ein MultiBinding nimmst und einen MultiValueConverter baust, der ein Objekt aus den gebundenen Daten macht.
Das geht, ist aber umständlich und fehleranfällig, außerdem kannst Du sowas nur schwer dynamisch steuern.
Oder Du nimmst einen MultiValueConverter, der einfach das Values-Array zurück gibt, dann bekommst Du im Command dieses Array und kannst es untersuchen, aber auch das halte ich für zu fehleranfällig, besonders da es bessere Lösungen gibt.

Ich würde stattdessen überlegen, ob ein eigenes ViewModel pro Hyperlink nicht die bessere Lösung ist. Da hast Du dann alle Infos drin, die Du brauchst und kannst alles aus dem "Haupt"-ViewModel heraus steuern.
Außerdem würde der XAML-Code weit übersichtlicher werden.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

H
habib Themenstarter:in
24 Beiträge seit 2020
vor 3 Jahren

Sollte ich für jedes Hyperlink ein eigenes ViewModel nehmen, dann hätte ich 6 Stück. nur für die Hyperlinks. Ansonsten hat meine Anwendung nur noch einen Button der das ganze speichert

Irgendwie habe ich das Gefühl, das hier das MVVM immens mehr Code hervorruft, als wenn ich alles gleich in der Code Behind geschrieben hätte.

Edit:
Oder geht es vlt. auch anders.
Ich möchte auswerten welcher TextBlock gelickt wurde, um entsprechend eine andere Information ausgeben zu lassen. Es soll in einer MessageBox stehen was kopiert wurde. Also der Text des Labels oder des TextBlocks. So könnte ich im ModelView entscheiden welchen Text ich aufgrund des geklickten ausgeben lasse.

2.079 Beiträge seit 2012
vor 3 Jahren

Ein eigenes ViewModel mit den Daten für Hyperlink, TextBox und was Du noch so benötigst und davon dann mehreren Instanzen pro Hyperlink.

Und ja, MVVM kann zu mehr Code führen, kann aber auch ordentlich Zeit und/oder Code einsparen. Aber auch mehr Code ist nichts schlechtes, diese Faulheit führt nämlich gerne dazu, dass man ganz grausiges Chaos baut 😛
Dieses grausige Chaos fällt allerdings erst später auf, wenn man nicht mehr zurück kann, deshalb gibt's ja sowas wie das MVVM-Pattern.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

H
habib Themenstarter:in
24 Beiträge seit 2020
vor 3 Jahren

Irgendwie kann ich nicht verstehen wie genau du das meinst.

An die StackPanels binde ich ein neues ViewModel? Und in diesem verarbeite ich dann die Daten des Hyperlinks? Aber wie bekomme ich die Daten aus dem HauptViewModel ohne CommandParamter rüber an das neue ViewModel?

2.079 Beiträge seit 2012
vor 3 Jahren

Das HauptViewModel erstellt das HyperlinkViewModel, also kann es damit auch tun und lassen, was es will.

public class HyperlinkViewModel
{
    public ICommand ClickCommand { get; }
    public string HyperlinkText { get; }
    public MyData Data { get; }

    public HyperlinkViewModel(/* ... */)
    {
        ClickCommand = ...
        HyperlinkText = ...
        MyData = ...
    }
}

public class MainViewModel
{
    public IEnumerable<HyperlinkViewmodel> Hyperlinks { get; }

    public HyperlinkViewModel Hyperlink1 { get; }
    public HyperlinkViewModel Hyperlink2 { get; }
    public HyperlinkViewModel Hyperlink3 { get; }

    public MainVieModel()
    {
        Hyperlinks = GetHyperlinks().ToArray();

        Hyperlink1 = new HyperlinkViewModel(/* ... */);
        Hyperlink2 = new HyperlinkViewModel(/* ... */);
        Hyperlink3 = new HyperlinkViewModel(/* ... */);
    }

    private IEnumerable<HyperlinkViewModel> GetHyperlinks()
    {
        yield return new HyperlinkViewModel(/* ... */);
        yield return new HyperlinkViewModel(/* ... */);
        yield return new HyperlinkViewModel(/* ... */);
        yield return new HyperlinkViewModel(/* ... */);
    }
}

An ein StackPanel kannst Du nicht (ohne Weiteres) binden, aber Du kannst an ein ItemsControl binden und dafür nutzt Du eine Liste der neuen Hyperlink-ViewModels.

Und wenn's keine Liste sein soll, dann eben direkt die Properties zum Hyperlink-ViewModel.

NuGet Packages im Code auslesen
lock Alternative für async/await

Beim CleanCode zählen nicht die Regeln, sondern dass wir uns mit diesen Regeln befassen, selbst wenn wir sie nicht befolgen - hoffentlich nach reiflichen Überlegungen.

5.658 Beiträge seit 2006
vor 3 Jahren

Aber wie bekomme ich die Daten aus dem HauptViewModel ohne CommandParamter rüber an das neue ViewModel?

Schau dir mal die Code-Beispiele und/oder das Beispiel-Projekt in [Artikel] MVVM und DataBinding an. Das ist tatsächlich ein Standard-Fall, den man im Grunde in jeder Anwendung hat.

Irgendwie habe ich das Gefühl, das hier das MVVM immens mehr Code hervorruft, als wenn ich alles gleich in der Code Behind geschrieben hätte.

Siehe dazu die einleitenden Sätze in [Artikel] MVVM und DataBinding

Weeks of programming can save you hours of planning