|
| » myCSharp.de Diskussionsforum |
|
|
|
|
Autor
 |
|
ErfinderDesRades
myCSharp.de-Poweruser/ Experte
Dabei seit: 31.01.2008
Beiträge: 4.413
|
|
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
myCSharp.de-Team (Moderation)
Dabei seit: 20.07.2003
Beiträge: 6.863
Entwicklungsumgebung: VS 2010 Herkunft: Esslingen
|
|
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
Dabei seit: 31.01.2008
Beiträge: 4.413
Themenstarter
|
|
| 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 
)
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
Dabei seit: 31.01.2008
Beiträge: 4.413
Themenstarter
|
|
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
|
|
|
|