ContentPresenter Content Binding Fehler

  • WP8

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von FlashTek.

    ContentPresenter Content Binding Fehler

    Hi,
    zur Zeit kämpfe ich etwas mit dem ContentPresenter Control von WP8. Erstmal: Mein Ziel ist es in einer Liste Bilder anzuzeigen, die sich an Hand von Enum-Werten per IValueConverter erstellen lassen sollen. Da ich svg-Grafiken nutzen wollte, habe ich gedacht, es würde reichen wenn ich in den Resourcen für jedes Bild einen Path deklarieren würde, dem ich die richtigen Daten gebe. Jetzt kommt nur ein Problem: Wie lasse ich die Paths anzeigen? Ganz naiv habe ich gedacht, es würde reichen per ContentPresenter und seiner Content Eigenschaft das ganze anzuzeigen. Aber leider geht das nicht, da die App mit der Fehlermeldung "Value does not fall within the expected range" abschmiert. Ich habe das jetzt erstmal so umgebaut, dass das Binding zu dem Enum per Converter draußen ist, und erstmal nur das Verknüpfen mit der statischen Resource getestet wird - und sogar das funktioniert nicht, da die App dann immer mit einer Exception abstürzt, und VS nicht einmal in der Lage ist, dieses irgendwie zu erhalten:/
    Mir mal mein bisheriger XAML-Code:
    Zum Erstellen des Paths in den Resourcen (etwas gekürzt):

    XML-Quellcode

    1. <phone:PhoneApplicationPage.Resources>
    2. <Path Data="F1 M 26.7982,56.6393L 29.831,56.1045C 29.1412,57.0897 27.7834,57.3291 26.7982,56.6393 Z" />
    3. </phone:PhoneApplicationPage.Resources>

    Verwendung des Paths:

    XML-Quellcode

    1. <Canvas Grid.Column="0" Height="100">
    2. <ContentControl Content="{StaticResource PlaceType_AppbarFoodSilverwareCross}"/>
    3. </Canvas>/>

    Wäre über Hilfe wirklich dankbar, da ich jetzt nach 4 stündigem Rumprobieren und Rumsuchen immer noch nicht wirklich weiter gekommen
    Generell liegt es daran, dass zwei Objekte den selben Namen im selben Parent haben. Vielleicht hilft es die ganzen Bindings rauszuhauen und alles in eine eigene Klasse zu machen, oder du schaust ma hier: digitaltoolfactory.net/blog/20…nge-error-in-silverlight/

    Ich hoffe ich hab dich richtig verstanden.
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Nicht wirklich. Da diese Fehlermeldug quasi eine der grundlegendsten in WPFartigen Umgebungen ist, kommt die fast bei jedem Markup Problem...
    ...ich konnte das ganze jetzt weiter reduzieren. Anscheinend ist es nicht möglich einen Path aus den Resourcen zu nehmen. Wenn man per Code einen neuen Path erstellt, und dessen Data auf die Data Property das Paths aus den Resourcen setzt, kommt exakt die gleiche Fehlermeldung.
    Jetzt habe ich mir gedacht: "Hey, clone einfach den Path aus den Resourcen und du bist fertig" - aber leider gibt es in WP8 keine Clone Methode bei den Shapes *grr*. Also bin ich nach etwas Suchen und Überlegen auf diese komische Lösung gekommen: Ich hau die Paths aus den Resourcen raus, und erstelle in meinem Converter jedes mal per XamlReader.Load() eine frische Instanz des Paths. Und ja, mir ist klar, dass diese Lösung absolut bescheuert ist - aber kennt jemand irgendwas sinnvolleres? :D
    Okay, jetzt bin ich nochmal etwas weitergekommen.
    Laut dem hier sind für WP8 2 Methoden möglich. Einmal die bereits von mir genutzte, und dann die, dass man das ganze über Styles regelt. Jetzt habe ich das mal versucht, und mir nen Style erstellt:

    XML-Quellcode

    1. <Style x:Key="pathStyle" TargetType="Path">
    2. <Setter Property="Data" Value="F1 M 57,47.5C 53.8333,34.29 53.8333,31.6667C 53.8333,29.0433 51.7067,26.9167 49.0833,26.9167L 49.0833,36.4167 Z" />
    3. </Style>

    Und bind den so ein:

    XML-Quellcode

    1. <Path Stroke="{StaticResource PhoneAccentBrush}" Style="{Binding Type, Converter={StaticResource PlaceTypeToCanvasPathConverter}}" />

    Jetzt gibt es nur ein Problem: Der Path wird immer nur beim ersten Element der Liste dargestellt, beim Rest nicht - ohne Fehlermeldung oder ähnlichem.
    Vielleicht hilft das weiter...
    @thefiloe: Wie gesagt: Ich muss nen Enum-Wert zu nem Path konvertieren. Deshalb kann ich den Style nicht so direkt setzen, sondern muss den Umweg über den Converter gehen.
    EDIT: Und wenn ich zum Testen den Style direkt aus den Resourcen setze, wird der Path trotzdem nur beim 1. Item dargestellt...
    Setze beim Path die x:Shared Eigenschaft auf false. Und schau ob er dann auch beim Rest angezeigt wird. Mach erstmal eines nach dem anderen und nicht gleich das mit dem Converter.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Ja, das ist nen Problem :D
    Hm, sofern ich nichts weiters finde werde ich das jetzt einfach per XamlLoader weitermachen. Ist zwar unschön, aber es funktioniert immerhin.
    ich find, du benutzt den ContentPresenter iwie komisch.
    Bei mir wird der Content immer an Daten gebunden, und im Scope befindet sich dann ein DataTemplate, was auf die Daten matcht.

    Also direkt ein Path käme bei mir als Content nie in Frage.

    Man kann auch für Enums DataTemplates schreiben. (jdfs. in wpf)
    @ErfinderDesRades: Ja, das ist alles etwas komisch gelöst, allerdings ist mir sonst kein funktionierender Weg eingefallen, wie ich den Path abhängig von dem Enum-Wert darstellen kann. Liegt vielleicht jetzt auch einfach daran, dass ich jetzt schon zu sehr in dieses Problem verbort bin, und irgendne offensichtliche Lösung komplett ausschließe...
    Edit: Wenn du da also nen schöneren Ansatz hast (denn ich selber finde das absolut unschön gelöst, meistens nur durch komische Beschränkungen von WP8) wäre ich dir dafür wirklich dankbar^^
    Edit2: Vielleicht kann man ja was über 'nen DataTemplateSelector regeln...

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „FlashTek“ ()

    @ErfinderDesRades: Schade. Genau das hatte ich auch schon mal am Anfang vor. Leider gibt es das Problem, dass VS mir dann beim Debuggen immer das hier entgegen wirft "Value does not fall within the expected range."
    Denke mal, dass das daran liegt, dass dann der eine Path der in den Resourcen definiert ist in mehreren Elementen dargestellt werden soll, oder? Denn sie wird erst geworfen, wenn der Converter das 2. mal mit dem gleichen Enum-Wert aufgerufen wird.
    also mit LookupConverter kannstes kaum ausprobiert haben, weil den gibts im FW nicht.
    jdfs. mit dem funzt bei mir folgendes:

    XML-Quellcode

    1. <Window x:Class="wndEnumBinding"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:my="clr-namespace:EnumBinding"
    5. xmlns:hlp="clr-namespace:System.Windows.Controls;assembly=WpfHelpers"
    6. xmlns:mda="clr-namespace:System.Windows.Media;assembly=PresentationCore"
    7. Title="EnumBinding" Height="210" Width="559"
    8. DataContext="{StaticResource MainModel}">
    9. <!--
    10. -->
    11. <hlp:GridEx ColumnDefs=",," RowDefs="," Name="GridEx1" AllowDrop="True">
    12. <FrameworkElement.Resources>
    13. <hlp:LookupConverter x:Key="Enum2Geometry">
    14. <hlp:LookupConverterColumn>
    15. <my:Number>One</my:Number>
    16. <my:Number>Two</my:Number>
    17. <my:Number>Three</my:Number>
    18. <!--<my:Action>Einschlafen</my:Action>-->
    19. </hlp:LookupConverterColumn>
    20. <hlp:LookupConverterColumn>
    21. <mda:PathGeometry>M-8,-8l16,16</mda:PathGeometry>
    22. <mda:PathGeometry>M-8,8l16,-16</mda:PathGeometry>
    23. <mda:PathGeometry>M-8,-8l16,16M-8,8l16,-16</mda:PathGeometry>
    24. </hlp:LookupConverterColumn>
    25. </hlp:LookupConverter>
    26. <DataTemplate DataType="{x:Type my:Number}">
    27. <Path Data="{Binding Converter={StaticResource Enum2Geometry}}" Stroke="Black" />
    28. </DataTemplate>
    29. </FrameworkElement.Resources>
    30. <ListBox Grid.Column="2" ItemsSource="{Binding Source={StaticResource Enum2Geometry}, Path=Keys}" IsSynchronizedWithCurrentItem="True" />
    31. <ContentPresenter Content="{Binding Source={StaticResource Enum2Geometry}, Path=Keys/}" Grid.Column="1" Grid.Row="1" />
    32. <ContentPresenter Content="{Binding Source={StaticResource Enum2Geometry}, Path=Keys/}" Grid.Column="2" Grid.Row="1" />

    Die Number - Enumeration sieht so aus:

    VB.NET-Quellcode

    1. Public Enum Number : One : Two : Three : End Enum
    (statt des GridEx' musste halt ein normales Grid nehmen)
    Hier auch der LookupConverter in Vb:

    VB.NET-Quellcode

    1. Imports System.Collections.ObjectModel
    2. Imports System.Collections.Specialized
    3. Namespace System.Windows.Controls
    4. <System.Windows.Markup.ContentProperty("Columns")> _
    5. Public Class LookupConverter : Implements IValueConverter
    6. 'usage in xaml: instantiate. add minimum 2 LookupConverterColumn, and fill them with items. first column is the key-Column, second the value-column, by default. if you add more columns, and want to convert a key to them, you must specify the column-valueColumnIndex by ConverterParameter. The filled Converter itself can be DataSource of ItemsControls
    7. ''' <summary> you can bind an ItemsSource direktly to the Keys in order to select from them </summary>
    8. Public ReadOnly Property Keys As IList(Of Object)
    9. Get
    10. If Columns.Count = 0 Then Return New Object() {}
    11. Return Columns(0).Items
    12. End Get
    13. End Property
    14. Public Property Columns As New List(Of LookupConverterColumn)
    15. Private Function Convert(ByVal key As Object, ByVal valueColumnIndex As Object, ByVal forward As Boolean) As Object
    16. Dim column = 1
    17. If valueColumnIndex IsNot Nothing Then Integer.TryParse(valueColumnIndex.ToString, column)
    18. If Not column.IsBetween(1, Columns.Count - 1) Then
    19. Throw Me.Exception("valueColumnIndex should match an existing Column-Index > 0")
    20. End If
    21. Dim lookIn = If(forward, Columns(0), Columns(column)).Items
    22. Dim returnFrom = If(forward, Columns(column), Columns(0)).Items
    23. Dim indx = lookIn.IndexOf(key)
    24. 'if returnFrom contains one item more than lookIn, use it as default-value in case of noMatch
    25. If indx < 0 Then indx = lookIn.Count
    26. Return If(indx >= returnFrom.Count, Nothing, returnFrom(indx))
    27. End Function
    28. ''' <summary> retrieves a value associated with key. valueColumnIndex = 1 by default. </summary>
    29. Public Function Convert(ByVal key As Object, ByVal targetType As Type, ByVal valueColumnIndex As Object, _
    30. ByVal culture As Globalization.CultureInfo) As Object Implements Data.IValueConverter.Convert
    31. Return Convert(key, valueColumnIndex, True)
    32. End Function
    33. ''' <summary> retrieves the key associated with value. valueColumnIndex = 1 by default. </summary>
    34. Public Function ConvertBack(ByVal value As Object, ByVal targetType As Type, ByVal valueColumnIndex As Object, _
    35. ByVal culture As Globalization.CultureInfo) As Object Implements Data.IValueConverter.ConvertBack
    36. Return Convert(value, valueColumnIndex, False)
    37. End Function
    38. End Class
    39. <System.Windows.Markup.ContentProperty("Items")>
    40. Public Class LookupConverterColumn
    41. Public Property Items As New List(Of Object)
    42. End Class
    43. End Namespace
    Das es den nicht im Franework gibt ist mir doch klar oO
    Ich meinte damit deinen Ansatz;)
    Das mit der PathGeometry ist aber etwas umständlicher einzugeben, als die Path Data direkt - oder ist das einfach das gleichen, nur das man Kommata statt Leerzeichen nutzn muss? Wenn ja habe ich erfolgreich einen Tag meines Lebens verschwendet - denn genau sowas hatte ich schon mal, bin aber daran gescheitert, dass mir das eingeben der pathGeometry zu aufwändig erschien. :D
    Edit: Anscheinend ist das nicht das gleiche. Und zum anderen kann man bei WP8 die PathGeometry nicht so setzen, das man das ganze über eine Collection von Figuren die aus einzelnen Segmenten bestehen müssen machen muss - so direkt kann man die Daten leider nicht setzen.
    @ErfinderDesRades: Noch eine Idee dazu?

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