Laden...

WPF Listbox SelectedItem Wert aus Teplate

Erstellt von MMCSharp vor einem Jahr Letzter Beitrag vor einem Jahr 618 Views
M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr
WPF Listbox SelectedItem Wert aus Teplate

Hallo

Ich habe eine Listbox mit einem ItemTemplate. Dieses Template implementiert mehrere StackPanel mit Textblöcken , die an eine ObservableCollection im VM gebunden sind.
Nun würde ich gern lediglich einen Wert (ID) des gewählten Item zurück geben und nicht das ganze Item. Wie lässt sich das im XAML lösen? (Ein Model des Item hab ich angehängt)

A
764 Beiträge seit 2007
vor einem Jahr

Hallo MMCSharp

So ganz verstanden habe ich das nicht, wie es bei dir aussieht. Ohne Code kann man da nur raten.

Prinzipiell würde ich sagen, dass du dafür einen IValueConverter verwendest: Wertumwandlung mit IValueConverter - The complete WPF tutorial

Gruß
Alf

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Ich würde gern einfach nur den Wert der ID des SelectedItem im VM binden und nicht das ganze Item. Aktuell bekomme ich das Item (das einem Model entspricht) nach der Selektierung.

16.834 Beiträge seit 2008
vor einem Jahr

Prinzipiell ist das auch die Idee, dass Du natürlich das "ganze" Item bekommst, weil das auch die Quelle darstellt.
Aber die ListBox unterstützt für gewisse Sachen auch mehr: How to: Use SelectedValue, SelectedValuePath, and SelectedItem - WPF .NET Framework (hier Sample TreeView, das Prinzip ist identisch).

PS: mit dem Bild kann wahrscheinlich fast niemand was anfangen. Auch ich hab keine Ahnung, was das darstellen soll.
Poste doch einfach ein Code Snippet?

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Hier der XAML- Codeausschnitt


                    <ListBox x:Name="ListLocations"
                            AlternationCount="2"
                            Background="#FF1F1F1F"
                            ItemContainerStyle="{DynamicResource _ListBoxItemStyle}"
                            SelectedItem="{Binding ID, Mode=twoWay}"
                            ItemsSource="{Binding WareHouseCollection}"
                            SelectedValuePath="@Id"
                            Margin="0,5,0,0"
                            Grid.Row="1" 
                            IsSynchronizedWithCurrentItem="True">
                       
                       
                        
                        <ListBox.ItemTemplate>
                            <DataTemplate x:Name="WareHouseTamplet">
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="Auto"/>
                                    </Grid.ColumnDefinitions>

                                    <!--#region Left Item area-->
                                    <Grid>

                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="50"/>
                                        </Grid.ColumnDefinitions>

                                        <Grid Grid.Column="0">
                                            <Grid.RowDefinitions>
                                                <RowDefinition Height="Auto"/>
                                                <RowDefinition Height="Auto"/>
                                            </Grid.RowDefinitions>

                                            <TextBlock Grid.Row="0" Name="LblID" 
                                                       Margin="5,0,0,0" FontSize="16" 
                                                       HorizontalAlignment="Left" Foreground="White" FontWeight="Bold" Text="{Binding Id}" />

                                            <svgc:SvgViewbox Width="25" Grid.Row="1" 
                                                             HorizontalAlignment="Left" VerticalAlignment="Center" 
                                                             Height="35" Source="Assets/Icons/right-arrow.svg" />

                                        </Grid>

                                    </Grid>

                                    <!--#endregion-->

                                    <!--#region Right Item area-->
                                    <Grid Grid.Column="1">
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="Auto"/>
                                        </Grid.RowDefinitions>

                                        <StackPanel Orientation="Horizontal" Grid.Row="0" Height="Auto">
                                            <TextBlock Name="LbLStockName" Margin="4,2,0,0" FontWeight="Bold" Foreground="White" Text="{Binding StockName}" Height="20"/>
                                        </StackPanel>

                                        <StackPanel Orientation="Horizontal" Grid.Row="1" Margin="0,3,0,0" Height="Auto">
                                            <TextBlock Name="LblStreet" Margin="5,0,0,0" Foreground="White" Text="{Binding Street}" Height="20"/>
                                            <TextBlock Name="LbLHousenumber" Margin="4,0,0,0" Foreground="White" Text="{Binding HouseNumber}" Height="20"/>
                                        </StackPanel>

                                        <StackPanel Orientation="Horizontal" Grid.Row="2" Height="Auto">
                                            <TextBlock Name="LblPostcode" Margin="5,0,0,2" Foreground="White" Text="{Binding Postcode}" />
                                            <TextBlock Name="LbLCity" Margin="4,0,0,2" Foreground="White" Text="{Binding City}" />
                                        </StackPanel>
                                    </Grid>
                                    <!--#endregion-->

                                </Grid>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>

und die Property im VM sieht momentan so aus


       private LocationModel? selectedItem;
       public LocationModel? SelectedItem
       {
            get { return selectedItem; }
            set
            {
                selectedItem = value;
                ID = value.Id;
                RaisePropertyChanged();
            }
       }

Nun würde ich aber gern einfach nur die Id als Property abgreifen:


   private int  id;
   public int ID
   {
            get { return id; }
            set 
            { 
                id = value;
                RaisePropertyChanged();
            }
     }

4.939 Beiträge seit 2008
vor einem Jahr

Das ergibt so aber keinen Sinn mit der Eigenschaft Id (so hättest du ja für die gesamte ListBox nur eine Id).

Willst du vllt. einfach so etwas?


public int SelectedID
{
    get { return SelectedItem?.Id; }
}

(ID = value.Id im Setter von SelectedItem ist dann überflüssig)

16.834 Beiträge seit 2008
vor einem Jahr

Wobei man so oder so dann auch nen Property Changed für die Id werfen sollte..
Sonst bekommt ja nie jemand was mit, wenn man nur auf die Id hört.

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Ich würde einfach nur gern aus dem ausgewählten Item die Id abgreifen und mit dieser dann weiter arbeiten, ohne das ganze Model im VM abzufangen. Es geht wohl auch so, aber mir gefällt die LocationModel Property nicht im VM. Deshalb würde ich gerne nur die ID Binden. Das würde ich gern schon im XAML so Biden, dass direkt die Id aus dem Item übergeben wird. Oder ist dieses Handling falsch?

16.834 Beiträge seit 2008
vor einem Jahr

Was klappt denn an der Erklärung nicht, die ich Dir weiter oben gegeben hab?
How to: Use SelectedValue, SelectedValuePath, and SelectedItem - WPF .NET Framework

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Entschuldigung @Abt .... Deine Lösung klappt und ist das was ich gesucht habe! Vielen Dank!

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Jetzt hab ich noch ein Problem. Die ListBox zeigt einen Fehler, wenn nichts selectirt ist. Der Rahmen wird dann rot. Lässt sich das unterdrücken?

4.939 Beiträge seit 2008
vor einem Jahr

Dann hast du einen Binding-Fehler, s.a. Mysterious red border appears around ComboBox (gilt für alle Listenelemente).

Wenn du int-Werte (also Wertetypen) bindest, dann muß ja immer ein Wert zugewiesen sein (und wenn es 0 ist), ansonsten auf int? (also Nullable<int>) binden.

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Super! Das hat geklappt! Dankeschön!