Laden...

ListView und WrapPanel

Erstellt von .tim vor 16 Jahren Letzter Beitrag vor 15 Jahren 9.407 Views
.
.tim Themenstarter:in
332 Beiträge seit 2006
vor 16 Jahren
ListView und WrapPanel

Hallo ich nutze ein ListView in dem die Elemente in einem WrapPanel angezeigt werden soll.

Die Anzeige soll später ähnlich wie die bekannte "Mininaturansicht" im Windows Explorer aussehen.

In meinem Test, soll die Hintergrundfarbe schwarz und die Textfarbe weiss sein. Das selektierte Elemente soll die Hintergrundfarbe ändern. In meinem Test habe ich dies mit Grün, Rot oder Gelb versucht. Leider funktioniert dies nicht. Bei dem Selektieren wird dies "Windows" Blau. Sobald das ListView den Fokus verliert. Wird der Hintergrund weiss und die Schrift ist dadurch sogar nicht mehr lesbar.

In meinem Test habe ich 3 Varianten probiert, dass sich die Farbe ändert. Ohne Erfolg.
Was habe ich falsch gemacht?

Das ListView ist folgendermassen instanziert.

 <ListView DockPanel.Dock="Top"
                          Style="{StaticResource style_mytest}" 
                          Background="Black">
                </ListView>

Das Style enthält einen eigene Typ. Das Bindung funktioniert wunderbar. Deshalb bitte die Angabe "myType" ignorieren.

<Style x:Key="style_mytest" TargetType="{x:Type ListView}">
        <Style.Triggers>
            <Trigger Property="IsFocused" Value="true">
                <Setter Property="Background" Value="Green" />
            </Trigger>
        </Style.Triggers>
        <Setter Property="FocusVisualStyle">
            <Setter.Value>
                <Style>
                    <Setter Property="Control.Background" Value="Yellow"></Setter>
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="ItemTemplate">
            <Setter.Value>
                <DataTemplate DataType="{x:Type myType}">
                    <DataTemplate.Triggers>
                        <Trigger Property="IsFocused" Value="true">
                            <Setter Property="Control.Background" Value="Red" />
                        </Trigger>
                    </DataTemplate.Triggers>
                        <TextBlock TextWrapping="Wrap" Width="150" Text="{Binding Path=ElementContent}" Foreground="White"/>
                </DataTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <WrapPanel Background="Black">
                    </WrapPanel>
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <ItemsPresenter />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Es wäre super, wenn mir jemand helfen könnte, da ich langsam am verzweifeln bin.

.
.tim Themenstarter:in
332 Beiträge seit 2006
vor 16 Jahren

Ich habe etwas ausprobiert, dass teilweise funktioniert.

Ich habe für das **ListView ** ein **ItemContainerStyle ** definiert. Dieses Style hat den **TargetType ****ListViewItem **und überschreibt das Template mit dem folgenden XAML Code. Es gibt 4 Probleme auf die mir keine oder keine gute Lösung einfällt.

  1. Damit **IsSelected **von dem Trigger gefunden werden kann, muss der **TargetType ****ListViewItem **sein. Die Items sind aber von dem Typen myType. Nun könnte ich von **ListViewItem **ableiten. Dabei bekomme ich aber Probleme mit dem OR-Mapper. Dieser stört sich daran, das manche Member nicht als virtual gekennzeichnet sind. Theoretisch könnte ich mir die Arbeit machen, und die Member neu erstellen und auf die Basisfunktionalität mappen. Sprich "... new virtual ..."

  2. Wie kann es sein, dass alles ordentlich dargestellt wird? Das **ImgPath **und **ElementContent **gefunden werden, kann ich mir damit erklären, dass **ListViewItem **als **TargetType **ignoriert wird und **myType **diese Eigenschaften enthält. Wie ist dies aber mit **IsSelected **und Selector.IsSelectionActive, diese Eigenschaften sind nicht in myType vorhanden und können trotzdem fehlerfrei genutzt werden (Die GUI funktioniert, wie sie soll).

  3. **TextBlock.Text **ist an **ElementContent **gebunden. Wie kann ich einen Prefix (statischer Text und eine Eigenschaft eines Singleton-Objekts) hinzufügen?

  4. Wie kann ich das **ControlTemplate **manipulieren. D.h. wie kann ich z.B. durch einen Trigger bei **IsSelected **die Breite des Bildes ändern.

<ControlTemplate TargetType="{x:Type ListViewItem}">
                                <Border Margin="10" BorderBrush="White" BorderThickness="5" CornerRadius="10" Padding="10" Background="{TemplateBinding Background}">
                                    <ContentControl HorizontalContentAlignment="Stretch" HorizontalAlignment="Center">
                                        <StackPanel>
                                            <Image Source="{Binding Path=ImgPath}" Width="150" Height="100" Stretch="Fill" Margin="5"/>
                                            <TextBlock 
                                                TextWrapping="Wrap" 
                                                Width="150" 
                                                Text="{Binding Path=ElementContent}" 
                                                Foreground="{TemplateBinding Foreground}"
                                                Background="{TemplateBinding Background}">
                                            </TextBlock>
                                        </StackPanel>
                                    </ContentControl>
                                </Border>
                                
                                <ControlTemplate.Triggers>
                                    
                                    <Trigger Property="IsSelected" Value="true">
                                        <!--Wenn das Item selected ist und aktiv-->
                                        <Setter Property="Background" Value="Black"/>
                                        <Setter Property="Foreground" Value="Yellow"/>
                                    </Trigger>
                                    <Trigger Property="IsSelected" Value="false">
                                        <!--Wenn das Item nicht selected ist-->
                                        <Setter Property="Background" Value="Yellow"/>
                                        <Setter Property="Foreground" Value="Black"/>
                                    </Trigger>
                                    <MultiTrigger>
                                        <MultiTrigger.Conditions>
                                            <Condition Property="IsSelected" Value="true"/>
                                            <Condition Property="Selector.IsSelectionActive" Value="false"/>
                                        </MultiTrigger.Conditions>
                                        <!--Wenn das Item selected ist und nicht aktiv-->
                                        <Setter Property="Background" Value="Black"/>
                                        <Setter Property="Foreground" Value="Orange"/>
                                    </MultiTrigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>

Es wäre super wenn ihr mir bei der einen oder anderen Fragen helfen könnt.

Vielen Dank.

.
.tim Themenstarter:in
332 Beiträge seit 2006
vor 15 Jahren

Hat niemand eine Antwort auf meine ganzen Fragen? 🙁

V
86 Beiträge seit 2008
vor 15 Jahren

Im Prinzip ist es ganz einfach:
Mach einfach das komplette Border in den Trigger rein und änder die Imagebreite.

.
.tim Themenstarter:in
332 Beiträge seit 2006
vor 15 Jahren

Im Prinzip ist es ganz einfach:
Mach einfach das komplette Border in den Trigger rein und änder die Imagebreite.

Wie meinst du das?
Wie kann ich aus dem Trigger den Border ansprechen?
Wie kann ich die anderen Elemente des ControlTemplates ändern?

Eine Idee zu Frage 1-3?

.
.tim Themenstarter:in
332 Beiträge seit 2006
vor 15 Jahren

Leider bestehen die Fragen noch immer.

Ich habe weiterhin mehr probiert, aber komme noch weiterhin auf die selben Ergebnisse.

Es wäre super, wenn mir jemand einen Tipp geben könnte. Ein Artikel der die Probleme/Fragen lösen könnte, wäre auch sehr hilfreich.

Vielen Dank
.tim

.
.tim Themenstarter:in
332 Beiträge seit 2006
vor 15 Jahren

Da nun etwas Zeit vergangen ist und ich leider trotz intensivem suchen leider die Fragen noch immer offen sind, wollte ich fragen, ob zwischenzeitlich jemand eine Idee auf meine Fragen/Probleme hat.

Für jede Idee, wo ich suchen könnte, wäre ich sehr dankbar.

354 Beiträge seit 2004
vor 15 Jahren

Könntest du mal deinen aktuellen Stand posten bzw. gleich dein Projekt anhängen?

.NET GUI - Die Community für grafische Oberflächen unter .NET
Jetzt kostenlos besorgen: .NET BlogBook
Norbert Eder
DasBackup

.
.tim Themenstarter:in
332 Beiträge seit 2006
vor 15 Jahren

Das ist der aktuelle Stand. Dabei geht es auch mehr um das Verständis der Sache.
Das komplette Projekt würde den Umfang sprengen.

Bitte les dir vorallem meinen 2ten Beitrag und die darin enthaltenen vorhanden Fragen durch. Dann verstehst du was ich grundlegend nicht verstehe.

354 Beiträge seit 2004
vor 15 Jahren
  1. Damit **IsSelected **von dem Trigger gefunden werden kann, muss der **TargetType ****ListViewItem **sein. Die Items sind aber von dem Typen myType. Nun könnte ich von **ListViewItem **ableiten. Dabei bekomme ich aber Probleme mit dem OR-Mapper. Dieser stört sich daran, das manche Member nicht als virtual gekennzeichnet sind. Theoretisch könnte ich mir die Arbeit machen, und die Member neu erstellen und auf die Basisfunktionalität mappen. Sprich "... new virtual ..."

Wie genau hängst du dein ListViewItem rein? Sagst du:


ListViewItem lvi = new ListViewItem();
lvi.Content = new MyType(myImgPath);

Eine ListView besteht nun aus Items. Jedes Item ist und bleibt ein ListViewItem. Was du aber über ein ControlTemplate machen kannst ist, dass du die Gestaltung eines ListViewItems austauschen kannst. Nicht aber, dass es sich nachwievor um ein ListViewItem handelt. Daher muss der TargetType auch ListViewItem sein, damit du Informationen beziehen kannst, die Rückschlüsse darauf zulassen, dass das Item selektiert wurde etc.

Dein Verständnisproblem an der Sache ist folgendes:
Du musst angeben, worauf sich das ControlTemplate bezieht. In deinem Fall ListViewItem. Ebenso möchtest du auf Ergeignisse des ControlTemplates reagieren. Dieses wird repräsentiert durch ein ListViewItem. Dieses definiert nun auch die Ereignisse, die du via Trigger abfangen kannst.

Das Binding jedoch, bezieht sich auf das was das ListViewItem enthält und nicht auf die ListViewItem selbst (das wäre das TemplateBinding).

So gesehen solltest du mit deinem O/R Mapper auch keine Probleme bekommen.

  1. Wie kann es sein, dass alles ordentlich dargestellt wird? Das **ImgPath **und **ElementContent **gefunden werden, kann ich mir damit erklären, dass **ListViewItem **als **TargetType **ignoriert wird und **myType **diese Eigenschaften enthält. Wie ist dies aber mit **IsSelected **und Selector.IsSelectionActive, diese Eigenschaften sind nicht in myType vorhanden und können trotzdem fehlerfrei genutzt werden (Die GUI funktioniert, wie sie soll).

Siehe oben.

  1. **TextBlock.Text **ist an **ElementContent **gebunden. Wie kann ich einen Prefix (statischer Text und eine Eigenschaft eines Singleton-Objekts) hinzufügen?

Kannst du da bitte genauer beschreiben, was du vor hast?

  1. Wie kann ich das **ControlTemplate **manipulieren. D.h. wie kann ich z.B. durch einen Trigger bei **IsSelected **die Breite des Bildes ändern.

Hier könntest du beispielsweise mit DataBinding arbeiten. Breite des Images wird beispielsweise an eine Eigenschaft deines Objektes gebunden, welches wiederum über den Trigger neu gesetzt werden kann (nicht getestet, müsste aber funktionieren).

.NET GUI - Die Community für grafische Oberflächen unter .NET
Jetzt kostenlos besorgen: .NET BlogBook
Norbert Eder
DasBackup

.
.tim Themenstarter:in
332 Beiträge seit 2006
vor 15 Jahren

Ersteinmal vielen Dank, das du dir das angeschaut hast.

EDIT:
Die Items gehen über den Source in das ListView als BindingList<>

1 u. 2) So ganz ist es mir nicht. Ich greife doch zB im Trigger auf Eigenschaften von ListViewItem (IsSelected) zu und binde auf der anderen Seite an Member von meinem Typ (ElementContent).

  1. Ich habe z.B. eine statische Eigenschaft in einem Singleton Objekt. In meinem Fall habe ich z. B. einen Pfad. Nun möchte ich gerne den ImageSource setzen, Pfad (nicht im Item vorhanden) + Dateiname. Wobei der Dateiname in dem Item vorhanden ist.

  2. D.h. um z.B. im ControlTemplate die Breite eines Image(Containers) per Trigger zu ändern, müsste ich diese Eigenschaft an eine (Dummy) Eigenschaft des Items binden?
    Nun sind wir aber bei Problem 1 u. 2. Im Trigger kann ich doch nur auf die Eigenschaften von ListViewItem und nicht meinem Typ zugreifen.

EDIT: Ich möchte z. B. bei nem IsSelected eine Animation starten oder so.

354 Beiträge seit 2004
vor 15 Jahren

Die Items gehen über den Source in das ListView als BindingList<>

Kein Problem, ist ja auch nur eine Collection deiner Objekte.

1 u. 2) So ganz ist es mir nicht. Ich greife doch zB im Trigger auf Eigenschaften von ListViewItem (IsSelected) zu und binde auf der anderen Seite an Member von meinem Typ (ElementContent).

Neuer Tag, neuer Versuch 😉

Und zwar: Durch das ControlTemplate legst du ja fest, für welchen Typ es zuständig ist bzw. in welchem Typ es verwendet wird. Dieser Typ IST ein ListViewItem. Dieses bietet Eigenschaften an, die verwendet werden können (IsSelected zum Beispiel).

Nun fügst du eigene Objekte der Items-Auflistung hinzu (DataSource, wie auch immer). Diese werden für das DataBinding verwendet, d.h. er findet so auch den angegebenen Pfad, weil pro ListViewItem auf das Objekt geachtet wird, das darin enthalten ist.

  1. Ich habe z.B. eine statische Eigenschaft in einem Singleton Objekt. In meinem Fall habe ich z. B. einen Pfad. Nun möchte ich gerne den ImageSource setzen, Pfad (nicht im Item vorhanden) + Dateiname. Wobei der Dateiname in dem Item vorhanden ist.

Du kannst das über einen ObjectDataProvider in deinen Ressourcen machen und da das Ergebnis einer Methode etc. binden.

  1. D.h. um z.B. im ControlTemplate die Breite eines Image(Containers) per Trigger zu ändern, müsste ich diese Eigenschaft an eine (Dummy) Eigenschaft des Items binden?
    Nun sind wir aber bei Problem 1 u. 2. Im Trigger kann ich doch nur auf die Eigenschaften von ListViewItem und nicht meinem Typ zugreifen.

Ich versuche die Zeit zu finden, dir da ein Beispiel zu erstellen.

.NET GUI - Die Community für grafische Oberflächen unter .NET
Jetzt kostenlos besorgen: .NET BlogBook
Norbert Eder
DasBackup

.
.tim Themenstarter:in
332 Beiträge seit 2006
vor 15 Jahren

Nocheinmal vielen Dank.

Und zwar: Durch das ControlTemplate legst du ja fest, für welchen Typ es zuständig ist bzw. in welchem Typ es verwendet wird. Dieser Typ IST ein ListViewItem. Dieses bietet Eigenschaften an, die verwendet werden können (IsSelected zum Beispiel).

Nun fügst du eigene Objekte der Items-Auflistung hinzu (DataSource, wie auch immer). Diese werden für das DataBinding verwendet, d.h. er findet so auch den angegebenen Pfad, weil pro ListViewItem auf das Objekt geachtet wird, das darin enthalten ist.

Das heisst also, ich kann sowohl "{Binding Path=EigenschaftMeinesTyp}" und "{Binding Path=EigenschaftListView}" nutzen?

Du hast geschrieben "Dieser Typ IST ein ListViewItem". Das ControlTemplate bezieht sich doch genau auf ein Item und das kann doch nur von einem Typ sein. Ich verstehe die Logik irgendwie nicht. Befinde ich mich in einem ListViewItem oder in einem Item von meinem Typ? Ich stelle mir das so vor, dass ich mich in dem Design Bereich einer foreach Schleife befinde. Ich hoffe du verstehst was ich meine.

Du kannst das über einen ObjectDataProvider in deinen Ressourcen machen und da das Ergebnis einer Methode etc. binden.

Ok danke, aber in dem Fall kann ich nun nur an den Pfad binden. Ich möchte aber sozusagen den Sourcestring aus 2 Bindungen zusammensetzen. D.h. sowas wie Pfad (Bindung1) + Dateiname (Bindung2).

Ich versuche die Zeit zu finden, dir da ein Beispiel zu erstellen.

Das wäre super.

Eine Kleinigkeit ist mir auch noch unklar. Wenn ich mich in dem ControlTemplate befinde, habe ich nur einen Bezug auf ein ListViewItem. Dieses ControlTemplate nutze ich in einem UserControl. Was ist aber wenn ich aus dem ControlTemplate auf Eigenschaften des UserControls zugreifen möchte. Ich habe da folgendes Problem. Mein UserControl hat eine Eigenschaft DefaultImageSource. Wenn kein ImagePath in meinen Items vorhanden ist, soll dieser DefaultImageSource genutzt werden. Meine Idee in der Sache wäre ein Trigger, der ja (wahrscheinlich) auf die Eigenschaften des Items zugreifen kann. Aber wie sag ich dem Trigger dann, dass er den ImageSource Pfad in dem Fall auf DefaultImageSource setzen soll?

354 Beiträge seit 2004
vor 15 Jahren

So, wie versprochen, hier ein kleines Beispiel. Es handelt sich dabei um ein Window und dieses besitzt mehr oder weniger nur eine ListView. Diese ListView bekommt über die ItemsSource eine Collection mit Elementen vom Typ Person, welcher wie folgt aussieht:


public class Person
{
    public String Firstname { get; set; }
    public String Lastname { get; set; }
    public String PicturePath { get; set; }
}

Nun wurde von mir das ControlTemplate ausgetauscht. Was macht dieses?

  1. Es stellt das jeweilige Element in einem Grid dar (ListViewItem). Die linke Spalte ist befüllt mit einem Image, in der rechten Zeile befinden sich zwei Zeilen. In der ersten wird der Nachname fett angezeigt, darunter der Vorname.

  2. Es ist darauf zu achten, dass den einzelnen Elementen im ControlTemplate ein Name zugewiesen wird. Dadurch kann über die Trigger darauf zugegriffen werden.

Hier nun das gesamte XAML-Markup:


<Window x:Class="DotNetGui.WpfListViewDemo.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title=".NET GUI - ListView - Resize Image Demo" Height="300" Width="300">

    <Window.Resources>

        <Style x:Key="{x:Type ListViewItem}" TargetType="{x:Type ListViewItem}">
            <Setter Property="SnapsToDevicePixels" Value="true"/>
            <Setter Property="OverridesDefaultStyle" Value="true"/>
            <Setter Property="Template">
                <Setter.Value>

                    <ControlTemplate x:Key="{x:Type ListViewItem}" TargetType="{x:Type ListViewItem}">
                        <Border Padding="2" SnapsToDevicePixels="true" Background="{TemplateBinding Background}">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="50"/>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="25"/>
                                    <RowDefinition Height="25"/>
                                </Grid.RowDefinitions>

                                <Image Name="PersonPicture" Source="{Binding Path=PicturePath}" Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Width="30"/>
                                <TextBlock Padding="2" Text="{Binding Path=Lastname}" FontWeight="Bold" Grid.Column="1" Grid.Row="0"/>
                                <TextBlock Padding="2" Text="{Binding Path=Firstname}" Grid.Column="1" Grid.Row="1"/>
                            </Grid>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter Property="Background" Value="LightBlue"/>
                                <Setter TargetName="PersonPicture" Property="Width" Value="50"/>
                            </Trigger>
                            <Trigger Property="IsSelected" Value="False">
                                <Setter Property="Background" Value="White"/>
                                <Setter TargetName="PersonPicture" Property="Width" Value="30"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

    <DockPanel>
        <ScrollViewer CanContentScroll="True" VerticalScrollBarVisibility="Auto">
            <ListView x:Name="PersonListView"/>
        </ScrollViewer>
    </DockPanel>
</Window>

Beachte bitte die Zeilen:

<Setter TargetName="PersonPicture" Property="Width" Value="50"/>

bzw.

<Setter TargetName="PersonPicture" Property="Width" Value="30"/>

Darüber kann direkt das Image-Element des ControlTemplates beeinflusst werden. Auf diese Weise kannst du sehr einfach (ohne sonstige Handgriffe zu tun), die Breite deines Images anpassen.

Ich hoffe das hilft dir soweit mal weiter bzw. zeigt dir auf, wie man Derartiges angehen kann. Hier noch der Screenshot meiner Beispielanwendung:

.NET GUI - Die Community für grafische Oberflächen unter .NET
Jetzt kostenlos besorgen: .NET BlogBook
Norbert Eder
DasBackup

.
.tim Themenstarter:in
332 Beiträge seit 2006
vor 15 Jahren

Vielen Dank. Genau soetwas hatte ich gesucht.

Falls du die Zeit findest, wäre es echt toll, wenn du noch meinen vorherigen Beitrag beantworten könntest.

354 Beiträge seit 2004
vor 15 Jahren

Das heisst also, ich kann sowohl "{Binding Path=EigenschaftMeinesTyp}" und "{Binding Path=EigenschaftListView}" nutzen?

Für den zweiten Fall gibt es das TemplateBinding. Mit Binding alleine kannst du entweder Eigenschaften des übergebenen Typs binden oder unter Angabe von ElementName Eigenschaften eines anderen Elemente.s

Du hast geschrieben "Dieser Typ IST ein ListViewItem". Das ControlTemplate bezieht sich doch genau auf ein Item und das kann doch nur von einem Typ sein. Ich verstehe die Logik irgendwie nicht. Befinde ich mich in einem ListViewItem oder in einem Item von meinem Typ? Ich stelle mir das so vor, dass ich mich in dem Design Bereich einer foreach Schleife befinde. Ich hoffe du verstehst was ich meine.

Ok, ich versuchs nochmal.
Ein ListView besitzt Items. Diese Items sind ursprünglich vom Typ ListViewItem. Dahingehend kann man dann beispielsweise ein ControlTemplate erstellen. Dieses wird auch auf die ListViewItems entsprechend angewandt. Wenn du nun die ItemsSource setzt, dann befindet sich in der Items-Auflistung eine Collection deiner Objekte.

Ok danke, aber in dem Fall kann ich nun nur an den Pfad binden. Ich möchte aber sozusagen den Sourcestring aus 2 Bindungen zusammensetzen. D.h. sowas wie Pfad (Bindung1) + Dateiname (Bindung2).

Erstelle dir eine Methode/Eigenschaft, welche dir den Gesamtpfad zurückgibt und diesen bindest du dann einfach.

Eine Kleinigkeit ist mir auch noch unklar. Wenn ich mich in dem ControlTemplate befinde, habe ich nur einen Bezug auf ein ListViewItem. Dieses ControlTemplate nutze ich in einem UserControl. Was ist aber wenn ich aus dem ControlTemplate auf Eigenschaften des UserControls zugreifen möchte. Ich habe da folgendes Problem. Mein UserControl hat eine Eigenschaft DefaultImageSource. Wenn kein ImagePath in meinen Items vorhanden ist, soll dieser DefaultImageSource genutzt werden. Meine Idee in der Sache wäre ein Trigger, der ja (wahrscheinlich) auf die Eigenschaften des Items zugreifen kann. Aber wie sag ich dem Trigger dann, dass er den ImageSource Pfad in dem Fall auf DefaultImageSource setzen soll?

Dein UserControl ist ja auch nur ein Element. Probiere es mit einem Binding unter Angabe des ElementName und verweise auf deine entsprechende Property. Achte darauf, dass es sich um eine DependencyProperty handelt. Das sollte funktionieren, ohne es jetzt getestet zu haben.

.NET GUI - Die Community für grafische Oberflächen unter .NET
Jetzt kostenlos besorgen: .NET BlogBook
Norbert Eder
DasBackup

.
.tim Themenstarter:in
332 Beiträge seit 2006
vor 15 Jahren

Vielen Dank.

... Wenn du nun die ItemsSource setzt, dann befindet sich in der Items-Auflistung eine Collection deiner Objekte.

Ok, also kann ich mir das folgendermassen vorstellen. Mein ListViewItem hat ein Child, welches mein Item aus dem Source entspricht. In meinem ControlTemplate bin ich auf der Ebene des Childs und kann deshalb mit Binding auf die Eigenschaften von meinem Typ zugreifen. Um nun wieder zu meinem Parent (dem ListViewItem) zu gelangen, muss ich TemplateBinding nutzen?

Habe mir das so hergeleitet, da Template Binding {Binding RelativeSource={RelativeSource TemplatedParent}} laut MSDN entspricht.

Erstelle dir eine Methode/Eigenschaft, welche dir den Gesamtpfad zurückgibt und diesen bindest du dann einfach.

Schade, dass soetwas nur so umständlich ist. Eine Möglichkeit wie Key="Mein Statischer Wert {Binding ...}" wäre viel praktischer 🙂

Dein UserControl ist ja auch nur ein Element. Probiere es mit einem Binding unter Angabe des ElementName und verweise auf deine entsprechende Property. Achte darauf, dass es sich um eine DependencyProperty handelt. Das sollte funktionieren, ohne es jetzt getestet zu haben.

In dem Fall dürfte ich das Template aber nicht in ein ResourceDictionary auslagern, da zu dem Zeitpunkt der ElementName noch garnicht exisiert, bzw. nicht bekannt ist, dass er jemals existieren wird. Somit kann ich wieder nicht wirklich Design zentral verwalten.

Eine Skinfähigkeit unter WPF durchzusetzen, ist meiner Meinung nach nicht einfacher als bei Windows Forms, leider 🙁

354 Beiträge seit 2004
vor 15 Jahren

Ok, also kann ich mir das folgendermassen vorstellen. Mein ListViewItem hat ein Child, welches mein Item aus dem Source entspricht. In meinem ControlTemplate bin ich auf der Ebene des Childs und kann deshalb mit Binding auf die Eigenschaften von meinem Typ zugreifen. Um nun wieder zu meinem Parent (dem ListViewItem) zu gelangen, muss ich TemplateBinding nutzen?

Nein, wenn du die ItemsSource-Eigenschaft zugewiesen hast, dann gibt es das ListViewItem so gesehen nicht mehr. Das würde es nur geben, wenn du folgendes hast:


<ListView>
  <ListViewItem>FirstItem</ListViewItem>
  <ListViewItem>SecondItem</ListViewItem>
</ListView>

In diesem Fall sähe der Logical Tree so aus:


ListView
 |- ListViewItem
     |- String
 |- ListViewItem
     |- String

Einfach mal mit dem LogicalTreeHelper bzw. dem VisualTreeHelper spielen 🙂

Schade, dass soetwas nur so umständlich ist. Eine Möglichkeit wie Key="Mein Statischer Wert {Binding ...}" wäre viel praktischer 🙂

Vielleicht geht es auch viel einfacher 🙂

.NET GUI - Die Community für grafische Oberflächen unter .NET
Jetzt kostenlos besorgen: .NET BlogBook
Norbert Eder
DasBackup

.
.tim Themenstarter:in
332 Beiträge seit 2006
vor 15 Jahren

Ich habe zwar nicht verstanden wieso das so ist, aber ich nehme es einfach mal so hin.

Vielen Dank für deine Hilfe.