myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
   » Plugin für Firefox
   » Plugin für IE7
   » Gadget für Vista
» Regeln
» Wie poste ich richtig?
» Datenschutzerklärung
» wbb-FAQ

Mitglieder
» Liste / Suche
» Stadt / Anleitung dazu
» Wer ist wo online?

Angebote
» ASP.NET Webspace
» Bücher
» Zeitschriften
   » dot.net magazin
» Accessoires

Ressourcen
» .NET-Glossar
» guide to C#
» openbook: Visual C#
» openbook: OO
» .NET BlogBook
» MSDN Webcasts
» dotnetjob.de
» Search.Net

Team
» Kontakt
» Übersicht
» Wir über uns
» Bankverbindung
» Impressum

» Unsere MiniCity
MiniCity
» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » GUI: WPF und Silverlight » [gelöst] Image in Combobox
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | An Freund senden | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

[gelöst] Image in Combobox

 
Beiträge zu diesem Thema Autor Datum
 [gelöst] Image in Combobox ErfinderDesRades 18.10.2010 14:15
 RE: [gelöst] Image in Combobox talla 18.10.2010 14:27
 RE: [gelöst] Image in Combobox ErfinderDesRades 18.10.2010 16:04
 was eleganteres ErfinderDesRades 18.10.2010 19:18

Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
ErfinderDesRades
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-3151.jpg


Dabei seit: 31.01.2008
Beiträge: 4.426


ErfinderDesRades ist offline

[gelöst] Image in Combobox

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hi!

gegeben eine mit Enumerationswerten gebundene Combobox.
Jetzt sollen die Enums mit Icons assoziiert werden.

Eine Lösung habichschon, mit Triggern im ItemTemplate:

XML-Code:
    <ComboBox
      Grid.Column="2"   Grid.Row="1"  SelectedItem="{Binding Path=RequestTreeParams.ActionFilter}"
>
      <my:ActionCode>UnFiltered</my:ActionCode>
      <my:ActionCode>Allow</my:ActionCode>
      <my:ActionCode>Deny</my:ActionCode>
      <ComboBox.ItemTemplate>
        <DataTemplate>
          <StackPanel Orientation="Horizontal">
            <Image Width="16" Height="16" >
              <Image.Style>
                <Style TargetType="Image">
                  <Style.Triggers>
                    <DataTrigger Binding="{Binding}" Value="UnFiltered">
                      <Setter Property="Source" Value="/DataClassTester;component/Icons/UnFiltered.ico"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding}" Value="Allow">
                      <Setter Property="Source" Value="/DataClassTester;component/Icons/Allow.ico"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding}" Value="Deny">
                      <Setter Property="Source" Value="/DataClassTester;component/Icons/Deny.ico"/>
                    </DataTrigger>
                  </Style.Triggers>
                </Style>
              </Image.Style>
            </Image>
            <TextBlock Text="{Binding }" Margin="2 1 0 1" />
          </StackPanel>
        </DataTemplate>
      </ComboBox.ItemTemplate>
    </ComboBox>

Aber ich dachte, man könnte das auch mit einem AlternationConverter lösen, wenn man die Image-Source an den Alternation-Index der Combo bindet.

XML-Code:
    <ComboBox  Grid.Row="1" SelectedIndex="0"
      ItemsSource="{Binding Path=RequestTreeParams.ViewModeItems}"
      SelectedItem="{Binding Path=RequestTreeParams.ViewMode}" AlternationCount="3"
>
      <ComboBox.Resources>
        <AlternationConverter x:Key="ImageSources">
          <ImageSource>/Icons/UnFiltered.ico</ImageSource>
          <ImageSource>/Icons/Allow.ico</ImageSource>
          <ImageSource>/Icons/Deny.ico</ImageSource>
        </AlternationConverter>
      </ComboBox.Resources>
      <ComboBox.ItemContainerStyle>
        <Style TargetType="{x:Type ComboBoxItem}">
          <Setter Property="Content">
            <Setter.Value>
              <StackPanel Orientation="Horizontal">
                <Image Width="16" Height="16" Source="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource FindAncestor, AncestorType=ComboBoxItem, AncestorLevel=1}, Converter={StaticResource ImageSources}}"/>
                <TextBlock Text="{Binding }" Margin="2 1 0 1" />
              </StackPanel>
            </Setter.Value>
          </Setter>
        </Style>
      </ComboBox.ItemContainerStyle>
    </ComboBox>

Da schmeisster aber ObjectNull-Exception, wenn man die Combo öffnen will.

Prinzipiell gefallen mir Trigger nicht sonderlich, jedenfalls, wenn es mehrmals dieselbe Property ist, die überwacht wird - da müsste es doch etwas eleganteres geben?

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von ErfinderDesRades am 18.10.2010 19:18.

18.10.2010 14:15 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
talla talla ist männlich
myCSharp.de-Team (Moderation)

images/avatars/avatar-3214.jpg


Dabei seit: 20.07.2003
Beiträge: 6.863
Entwicklungsumgebung: VS 2010
Herkunft: Esslingen


talla ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

was ist denn Null? Das müsst die Excpetion doch hergeben. Ansonsten dürfte deine RelativeSource nichts finden da du ja nur eine Ebene drüber suchst und dort erst dein StackPanel ist. Desweiteren sind die URIs bei den Bildern anders, muss nicht falsch sein, kann aber wenn der untere Code den oberen ersetzen soll.
18.10.2010 14:27 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
ErfinderDesRades
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-3151.jpg


Dabei seit: 31.01.2008
Beiträge: 4.426

Themenstarter Thema begonnen von ErfinderDesRades

ErfinderDesRades ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von talla:
was ist denn Null?

System.NullReferenceException wurde nicht behandelt.
Message=Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
Source=PresentationFramework
StackTrace:
bei System.Windows.Controls.Primitives.Popup.OnWindowResize(Object sender, AutoResizedEventArgs e)
bei System.Windows.Interop.HwndSource.Resize(Size newSize)
bei System.Windows.Interop.HwndSource.OnLayoutUpdated(Object obj, EventArgs args)
bei System.Windows.ContextLayoutManager.fireLayoutUpdateEvent()
bei System.Windows.ContextLayoutManager.UpdateLayout()
bei System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
bei System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork()
bei System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
bei System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
bei System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
bei System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
bei MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
bei System.Windows.Threading.DispatcherOperation.InvokeImpl()
bei System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
bei System.Threading.ExecutionContext.runTryCode(Object userData)
bei System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
bei System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
bei System.Windows.Threading.DispatcherOperation.Invoke()
bei System.Windows.Threading.Dispatcher.ProcessQueue()
bei System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
bei MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
bei MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
bei System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
bei MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
bei System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
bei MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
bei MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
bei System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
bei System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
bei System.Windows.Threading.Dispatcher.Run()
bei System.Windows.Application.RunDispatcher(Object ignore)
bei System.Windows.Application.RunInternal(Window window)
bei System.Windows.Application.Run(Window window)
bei System.Windows.Application.Run()
bei DataClassTester.Application.Main() in C:\Programming\VS10\VB10\DataClassTester\DataClassTester\obj\x86\Release\Ap
plication.g.vb:Zeile 77.
bei System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
bei System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
bei System.Threading.ThreadHelper.ThreadStart()
InnerException:

Das mit der RelativeSource habich so verstanden, dasser nach oben sucht, bisserwas gefunden hat, und AncestorLevel=1 sagt ihm, er soll den ersten Treffer nehmen, und nicht noch höher gehen (Quelle: irgendwo im Internet Augenzwinkern )

Die Uris habich per PropertyWindow für ein Image eingestellt, und dann in den Style kopiert.
18.10.2010 16:04 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
ErfinderDesRades
myCSharp.de-Poweruser/ Experte

images/avatars/avatar-3151.jpg


Dabei seit: 31.01.2008
Beiträge: 4.426

Themenstarter Thema begonnen von ErfinderDesRades

ErfinderDesRades ist offline

was eleganteres

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich hab jetzt einen Dictionary-artigen Converter gebastelt:

C#-Code:
using System.Collections.Generic;
using System.Windows.Data;

namespace System.Windows.Controls {

   [System.Windows.Markup.ContentProperty("Keys")]
   public class XamlDictionary : IValueConverter {

      public List<object> Keys { get; set; }
      public List<object> Values { get; set; }

      public object Convert(
            object value, Type targetType, object parameter, Globalization.CultureInfo culture) {
         var indx = Keys.IndexOf(value);
         return indx < 0 ? null : Values[indx];
      }

      public object ConvertBack(
            object value, Type targetType, object parameter, Globalization.CultureInfo culture) {
         var indx = Values.IndexOf(value);
         return indx < 0 ? null : Keys[indx];
      }
   }

}

Den kann ich nun befüllen und verwenden:

XML-Code:
    <Grid.Resources>
      <hlp:XamlDictionary x:Key="ActionCodeImages">
        <my:ActionCode>UnFiltered</my:ActionCode>
        <my:ActionCode>Allow</my:ActionCode>
        <my:ActionCode>Deny</my:ActionCode>
        <hlp:XamlDictionary.Values>
          <ImageSource>/Icons/UnFiltered.ico</ImageSource>
          <ImageSource>/Icons/Allow.ico</ImageSource>
          <ImageSource>/Icons/Deny.ico</ImageSource>
        </hlp:XamlDictionary.Values>
      </hlp:XamlDictionary>
    </Grid.Resources>
    <ComboBox ItemsSource="{Binding Source={StaticResource ActionCodeImages}, Path=Keys}">
      <ComboBox.ItemTemplate>
        <DataTemplate>
          <StackPanel Orientation="Horizontal">
            <Image Width="16" Height="16" Source="{Binding Converter={StaticResource ActionCodeImages}}"/>
            <TextBlock Text="{Binding }" Margin="2 1 0 1" />
          </StackPanel>
        </DataTemplate>
      </ComboBox.ItemTemplate>
    </ComboBox>

Hier habe ich ActionCodeImages.Keys gleich als ItemsSource der Combo verwendet - ich könnte die Combo auch anders mit ActionCode-Enumerationswerten befüllen, und so nur einen Ausschnitt der ActionCodeImages anbieten.
Ausserdem kannich natürlich dieses Dictionary in mehreren Combos verwenden.

Der Converter ist übrigens noch nicht ausgereift - ich versuche ihn zu einer LookUp-Tabelle mit variabler SpaltenAnzahl zu kriegen, und als ConverterParameter könnte man dann die Spalte angeben, die ausgespuckt wern soll.
(Wäre hier interessant für eine ToolTip-Description-Spalte der Combo-Einträge).
18.10.2010 19:18 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 2 Jahre.
Der letzte Beitrag ist älter als 2 Jahre.
Antwort erstellen


© Copyright 2003-2013 myCSharp.de-Team. Alle Rechte vorbehalten. 18.06.2013 23:44