WPF und GetImage

  • WPF
  • .NET 5–6

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von MasterQ.

    WPF und GetImage

    Hallo,

    nutzt man Ribbons unter Winforms benötigt man u.a. folgende Methode als CallBack:

    C#-Quellcode

    1. public Bitmap GetImage(IRibbonControl control)
    2. {
    3. return Properties.Public.mybitmap
    4. }


    Nun gibt es aber bei WPF kein Bitmap und ich steh auf dem Schlauch, wie ich das in WPF entsprechend zu ändern habe.

    Image kann ich nicht nehmen, denn Image ist ein UI-Element, das ein Bild anzeigt aber selbst kein Bild ist. Ich muss aber ein Bild zurückgeben.

    Wahrscheinlich denke ich wieder viel zu kompliziert und alles ist ganz einfach.

    Kann mir da jemand auf die Sprünge helfen? Folgendes funktioniert erstmal nicht. Immerhin kommt kein Compiler oder Laufzeitfehler. Das Icon im Ribbon bleibt aber leer.

    C#-Quellcode

    1. public BitmapImage GetImage(IRibbonControl control)
    2. {
    3. BitmapImage img = new();
    4. using (var s = new MemoryStream(Resources.dialog_ok_2))
    5. {
    6. img.BeginInit();
    7. img.CacheOption = BitmapCacheOption.OnLoad;
    8. img.StreamSource = s;
    9. img.EndInit();
    10. }
    11. return img;
    12. }


    Gruß

    MQ

    -- Edit:

    Das Bild wird nachweislich geladen und ist nach der Initialisierung auch "anzeigbar", d.h. img wurde korrekt gefüllt. Ist also ein Ribbon Ding.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „MasterQ“ ()

    Ich habe keine Ahnung was Ribbons sind.
    aber vielleicht erklärst du mal was du überhaupt vor hast. Vielleicht kann man einen anderen Weg finden.
    Rechtschreibfehler betonen den künstlerischen Charakter des Autors.
    ohne zu wissen, was Ribbons sind, wird's schon schwierig.

    Ribbon heißt Band und ist dieses Menuband in Office z.B. in Word:




    Ich schreibe ein Addin für Excel (ExcelDNA) und auch Excel nutzt diese Ribbon-Menus. Mein AddIn soll in der Lage sein, Fenster zu öffnen und nicht nur UDF (User Defined Functions) bereitstellen. Diese Fenster sollen WPF-Fenster sein, weil ich von WinForms weg will.

    Um dieses AddIn nutzen zu können, muss ich mich in das Menu von Excel einklinken und ein eigenes Ribbon definieren. Das klappt gut. Nun können die einzelnen Menupunkte mit Icons versehen werden (siehe oben). Das funktioniert über Callbacks (üblicherweise GetImage genannt), die im Ribbon-XML angegeben werden




    Das es sich um ein Ribbon in Office handelt, kann man nicht die Features nutzen, die man bei RibbonWindow unter WPF zur Verfügung hat, sondern muss eher die Mechanismen nutzen, die man evtl. noch von VBA kennt.

    Unter Winforms muss GetImage Bitmap zurückgeben was es in WPF so nicht gibt. Das nennt sich anders und wird auch anders behandelt.

    Ich habe jetzt rumgespielt mit verschiedenen Ansätzen, welchen Typ GetIMage bei WPF zurückgeben muss. Bisher ohne Erfolg. Mit BitmapImage (siehe mein Post oben) kam ich am weitesten, denn es kommen keine Cast Fehler und auch nix zur Laufzeit. Nur bleibt der Platz des Icons im Menu leer, obwohl das Bildchen korrekt eingelesen wird.



    Und ich weiß nicht warum!
    Also ich habe einfach mal ein Ribbon auf ein Window gepackt, nur mit einem Button.

    Dessen SmallImageSource an eine string-property im ViewModel gebunden, Image wird angezeigt.

    XML-Quellcode

    1. <Window x:Class="WpfApp1.MainWindow"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    6. xmlns:local="clr-namespace:WpfApp1"
    7. mc:Ignorable="d"
    8. Title="MainWindow" Height="450" Width="800">
    9. <Window.DataContext>
    10. <local:MainWindowViewModel/>
    11. </Window.DataContext>
    12. <Grid>
    13. <Grid.RowDefinitions>
    14. <RowDefinition Height="Auto"/>
    15. <RowDefinition/>
    16. </Grid.RowDefinitions>
    17. <Ribbon>
    18. <Ribbon.QuickAccessToolBar>
    19. <RibbonQuickAccessToolBar>
    20. <RibbonButton SmallImageSource="{Binding ImageFilename}" />
    21. </RibbonQuickAccessToolBar>
    22. </Ribbon.QuickAccessToolBar>
    23. </Ribbon>
    24. </Grid>
    25. </Window>

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.ComponentModel;
    4. using System.Linq;
    5. using System.Runtime.CompilerServices;
    6. using System.Text;
    7. using System.Threading.Tasks;
    8. namespace WpfApp1
    9. {
    10. public sealed class MainWindowViewModel : INotifyPropertyChanged
    11. {
    12. public event PropertyChangedEventHandler PropertyChanged;
    13. private void RaisePropertyChanged([CallerMemberName] string propertyName = "")
    14. {
    15. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    16. }
    17. public MainWindowViewModel()
    18. {
    19. ImageFilename = "Z:\\Images\\testImage.png";
    20. }
    21. private string _imageFilename = string.Empty;
    22. public string ImageFilename
    23. {
    24. get => _imageFilename;
    25. set
    26. {
    27. if(!_imageFilename.Equals(value))
    28. {
    29. _imageFilename = value;
    30. RaisePropertyChanged("ImageFilename");
    31. }
    32. }
    33. }
    34. }
    35. }
    Ja Bitbrösel,

    das sagte ich. Eine reine WPF-Anwendung macht man so wie du das aufgezeigt hat. Das funzt aber nicht mit Excel, weil Excel kein C# ist und man über ComInterop gehen muss. Die Schnittstelle bietet das (Nuget)Paket ExcelDNA. Hier mal ein Codeausschnitt der Hauptklasse. Hier wird eine Kopie des IRibbonUI gespeichert.




    und die Callbacks gehen über ein IRibbonControl, siehe den Ausschnitt der OnAction Callback Funktion.



    Wie das mit dem XML der Ribbondefinition zusammenkommt, zeigt mein Post oben mit dem XML-Ausschnitt.

    Das ist alles bissl anders als bei reinem WPF. Wer mal früher das mit VBA gemacht hat, findet alles sehr vertraut.

    Aber, damit wir uns nicht verzetteln. Meine Frage ist, ob jemand weiß, wie ich in dieses Office-Ribbon ein Bildchen über die Callback GetImage kriege. Ich weiß, das ist Nieschenwissen, aber vielleicht weiß es ja trotzdem eine/r.

    N'8 vorerst.