DelegataWiele kontrolek w WPF,Windows Forms i Silverlight ma właściwość “Tag”. W niej możemy przechowywać dowolny obiekt powiązany z daną kontrolką.

W tym wpisie pokaże jak użyć delegat wraz z właściwością Tag. Każda kontrolka z właściwością tag może użyć tej techniki. Dla uproszczenia wpisu ja skorzystałem z kontrolki Button.

Delegata nie zwraca wartości i przyjmuje tylko wartość typu string.

public delegate void DelegateShowMyMessage(string value);

Delegata ta będzie owinięta klasą “SupriseMessage”. Klasa ta będzie zawierać dodatkowe pole określającą nazwę wywołanej metody.

public class SupriseMessage
{
    public DelegateShowMyMessage Delegate { get; private set; }
    public string MetaData {get; private set;}

    public SupriseMessage(DelegateShowMyMessage de,string metadata)
    {
        Delegate = de;
        MetaData = metadata;
    }
}

Aplikacja WPF zawiera listę przycisków.

image

<Window x:Class="TagDelegateWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    <StackPanel Name="stackPanelButtons">
        <Button Content="WPF" Height="43" Click="Button_Click"/>
        <Button Content="WCF" Height="43" Click="Button_Click" />
        <Button Content="ASP.NET" Height="43" Click="Button_Click"/>
        <Button Content="Windows Forms" Height="43" Click="Button_Click"/>
        <Button Content="ASP.NET MVC" Height="43" Click="Button_Click"/>
        <Button Content="ADO.NET" Height="43" Click="Button_Click" />
        <Button Content="ADO.NET Enity Framework" Height="43" Click="Button_Click"/>
    </StackPanel>
</Window>

Do każdego przycisku we właściwości Tag dodamy instancje klasy “SupriseMessage”. Metoda zostanie losowo przypisana do delegaty.

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    Random r = new Random();

    foreach (Button button in stackPanelButtons.Children.OfType<Button>())
    {
        int ran = r.Next(3);
        if (ran == 0)
        {
            button.Tag = new SupriseMessage
                (new DelegateShowMyMessage(ShowMessage), "Method: ShowMessage");
        }
        else if (ran == 1)
            button.Tag = new SupriseMessage
                (new DelegateShowMyMessage(ShowMessage2), "Method: ShowMessage2");
        else
            button.Tag = new SupriseMessage
                (new DelegateShowMyMessage(ShowMessage3), "Method: ShowMessage3");
    }
}
public void ShowMessage(string value)
{
    MessageBox.Show("Moja ulubiona technologia .NET: " + value);
} 

public void ShowMessage2(string value)
{ 
    MessageBox.Show("Ciekawa technologia .NET: " + value);
} 

public void ShowMessage3(string value)
{ 
    MessageBox.Show("Wiedz, że lubie tą technologię: " + value);
}

Po naciśnięciu przycisku element tag zostanie skonwertowany na klasę SupriseMessage. Metoda przechowywana w delegacie zostanie uruchomiona.

private void Button_Click(object sender, RoutedEventArgs e)
{
    var button = (Button)e.Source;
    var suprise = ((SupriseMessage)button.Tag);
    suprise.Delegate.Invoke(button.Content.ToString() + "\n\n" + suprise.MetaData);
}

W ten sposób możesz definiować kod wykonawczy we właściwości Tag w kontrolce.

Edit z 2022 roku : Kod jest na GitHubie : PanNiebieski/TagDelegateWPF (github.com)