Laden...

WPF Combobox: Binding auf Selected Item???

Erstellt von tonka vor 15 Jahren Letzter Beitrag vor 15 Jahren 26.060 Views
tonka Themenstarter:in
373 Beiträge seit 2006
vor 15 Jahren
WPF Combobox: Binding auf Selected Item???

Hallo,

ich versuche gerade verzweifelt das SelectedItem ein WPF ComboBox an eine lokales Object zu binden. Ich habe mit google zwar einige Beispiele gefunden, jedoch funktioniert keines! Hier ist eine kurzer Ausschnitt aus meinem Source-Code den ich bis jetzt habe:


...
public class TestClass
{
    public Object SelObject = null;
    public ObservableCollection<String> ElementList = null;
    
    public TestClass()
    {
         ElementList = new ObservableCollection<String>(){"a","b","c"};         
         Combo.ItemSource = ElementList ;
    }
....
}

Das mit dem ItemSource funktioniert!

Mein XAML Code Sie folgendermaßen aus:


<ComboBox SelectedValue="{Binding Path=SelObject }" Name="Combo" HorizontalAlignment="Left" Width="150" IsSynchronizedWithCurrentItem="True" />

Ich weiß nicht was ich immer falsch mache, bei allen anderen Dingen wie z.B. bei einer TextBox funktioniert das Prima.

Weiß jemand von euch wie ich das richtig schreiben müsst, um das SlectedItem an ein lokales Object zu binden???

MfG
Tonka

3.430 Beiträge seit 2007
vor 15 Jahren

Hallo tonka,

versuche mal im Binding anstatt dem SelectedValue das SelectedItem-Property zu verwenden.
Also so:


<ComboBox SelectedItem="{Binding Path=SelObject }" Name="Combo" HorizontalAlignment="Left" Width="150" IsSynchronizedWithCurrentItem="True" />

Denn im SelObject - Object wird ja nicht der Wert des Objects sondern das Object selbst stehen (oder hast du das da anders gelöst?).

Gruss
Michael

tonka Themenstarter:in
373 Beiträge seit 2006
vor 15 Jahren

Hy michlG,

hat leider auch nicht funktioniert. Hast noch eine andere Idee? Im Anhang findest du das kleine Test-VS-Solution!

Und hier ist der Code:

XAML:


<Window x:Class="ComboboxBindingTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <ComboBox SelectedItem="{Binding Path=SelObject}" Margin="80,0,78,129" Name="Combo" IsSynchronizedWithCurrentItem="True" Height="23" VerticalAlignment="Bottom" />
        <Button Height="23" Margin="96,32,106,0" Name="button1" VerticalAlignment="Top" Click="button1_Click">Button</Button>
    </Grid>
</Window>

Und die *.cs dazu


using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ComboboxBindingTest
{
    /// <summary>
    /// Interaktionslogik für Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Object SelObject = null;
        public ObservableCollection<String> ElementList = null;

        public Window1()
        {
            InitializeComponent();

            ElementList = new ObservableCollection<String>() { "a", "b", "c" };
            Combo.ItemsSource = ElementList;
            Combo.DataContext = this;
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            if (SelObject == null)
            {
                MessageBox.Show("null");
            }
            else
            {
                MessageBox.Show(SelObject.ToString());
            }
        }
    }
}

MfG
Tonka

3.430 Beiträge seit 2007
vor 15 Jahren

Hallo tonka,

sorry aber ich habe vorhin gemeint dass du das Gegenteil machen willst (also das SelectedItem mit dem SelObject setzen und nicht das Gegenteil.

Habe gerade versucht das zu lösen, ich bin aber auch gescheitert Heute habe ich aber leider nicht mehr die Zeit mir das genauer anzusehen.

Gruss
Michael

U
1.578 Beiträge seit 2009
vor 15 Jahren

ich wuesste nicht wie das geht - aber warum machst du es nicht so?

public Object SelObject
{
    get { return Combo.SelectedItem; }
}
tonka Themenstarter:in
373 Beiträge seit 2006
vor 15 Jahren

hey,

ich wollte alles mit binding machen, weil sich hierbei so schön die GUI von der Geschäftslogik trennen lässt. Aber so wie's aussieht werd ich es wohl so machen müssen!

MfG
Tonka

U
1.578 Beiträge seit 2009
vor 15 Jahren

die trennung xaml-cs ist eh nicht elegant - die xaml und cs gehoeren zusammen - wenn du trennen moechtest sollte die cs auch nur gui sachen und verbindungen erledigen, und ueber schnittstellen zu anderen objekten laufen (zb nen controller oder so)
dann kannst du ganz einfach ein event holen wenn die selektion geaendert wurde - und das entsprechende objekt in deinen anderen objekten weiter reichen

zb
MainView.xaml+MainVIew.cs <=> Controller.cs <=> Model
OnSelectItem => Controller.SelectedObject [=> Model]

am besten machst du das auch ueber events und feddich

die view kannst du auch noch einzeilen und so ueber commands entsprechend reagieren
so hat sich das MVP bei mir schon bewaert

View1 <=>
View2 <=> Dispatcher (MainWindow) <=> Controller.cs <=> Model
View3 <=>

Der dispatcher gibt auftraege an dem controller - der macht das voodo und speichert daten in model und sagt dem dispatcher was an zu zeigen ist - dieser verteilt die anzeigen dan an dem entsprechenden view

schon hast du die beste trennung - kannst jederzeit die views austauschen {o;
die kommunikatin der views zum dispatcher dann ueber commands, dann braucht der dispatcher nichtmla wissen welche view was an gestossen hat

5.742 Beiträge seit 2007
vor 15 Jahren

die trennung xaml-cs ist eh nicht elegant - die xaml und cs gehoeren zusammen - wenn du trennen moechtest sollte die cs auch nur gui sachen und verbindungen erledigen, und ueber schnittstellen zu anderen objekten laufen (zb nen controller oder so)

Doch, normalerweise sollte unter WPF die *.cs Datei leer bleiben.

MainView.xaml+MainVIew.cs <=> Controller.cs <=> Model
OnSelectItem => Controller.SelectedObject [=> Model]

Unter WPF sollte man nur noch MVVM verwenden; weder MVC, noch sonstige "veraltete" Pattern.

tonka Themenstarter:in
373 Beiträge seit 2006
vor 15 Jahren

@Mr Evil:

Da hast du mich falsch verstanden, i möchte nicht MainView.xaml und MainView.cs trennen, sondern die Übergabe der Instanz (der GUI) an die GUI-Element (wie z.B. textbox, Combobox, etc.) selbst auf ein Minimum beschränken!

Meine Vorgehensweiße sieht nach Möglichkeit immer folgendermaßen aus:

Controller <=> GUI

Bei mir gibts immer nur Controller, die GUI steuern, alles andere ist pfusch, den so bleibt die GUI austauschbar (bis auf kleinigkeiten g). Bin dieses Prinzip noch sehr aus C++ gewohnt!

Binding finde ich aus dem Grund sehr interessant und empfehlenswert, da es automatisch (laut meiner erfahrung) immer Multitasking fähig ist, ohne dafür eine einzige Zeile Code schreiben zu müssen!

Außerdem bin ich auch der Ansicht von winSharp93, das die cs der xaml am besten leer wäre, was ja nicht ganz funkt, da ja schließlich events, parameterübergaben etc. in der GUI deklariert werden müssn, damit der Controller auf die Ereignisse auch reagieren kann!
Es sollte in WPF wirklich das MVVM Pattern benutzt werden ,sofern es möglich ist!(http://www.codecomplete.de/blogs/xamlblog/archive/2007/09/20/mvc-model-view-controller-reloaded-as-mvvm-model-view-viewmodel.aspx)

MfG
Tonka

U
1.578 Beiträge seit 2009
vor 15 Jahren

das die cs datei meist nahezu leer ist bestreite ich ja nicht - wie gesagt gehoert die xaml und cs datei zusammen - dh ob es wie in der frage per property aus dem element geholt wird, oder es gebunden wird, spielt dann absolut keine rolle

zugegeben - das MVC war eigentlich nur mein ansatz
ich hatte es bei mir schon laenger zu

view <=> dispatcher <=> controller
umgebaut - was dem
view <=> modelview <=> model
gleicht in meinem code #gg

namen sind schall und rauch

T
179 Beiträge seit 2007
vor 15 Jahren

also ich beteilige mich hier mal nicht an der pattern diskussion, sondern liefere einfach mal das, was der TE meiner Meinung nach gesucht hat:
Dieser Code

<ComboBox SelectedItem="{Binding Path=SelObject }" Name="Combo" HorizontalAlignment="Left" Width="150" IsSynchronizedWithCurrentItem="True" />  

bewirkt, dass das SelectedItem der ComboBox mit dem SelObject ersetzt wird.
Wenn du also SelObject änderst, ändert sich auch das ausgewählte Item der ComboBox.
Du solltest dir das mal anschauen Link
Wenn du also noch ein "Mode=OneWayToSource" einfügst

<ComboBox SelectedItem="{Binding Path=SelObject, Mode=OneWayToSource}" Name="Combo" HorizontalAlignment="Left" Width="150" IsSynchronizedWithCurrentItem="True" />  

dann ändert sich das SelObject, wenn du die Auswahl der ComboBox veränderst.
Hintergrund:
mit "Property={Binding Path=AnotherProperty}" bindest du Property an AnotherProperty, Property ist also das Ziel, das sich ändert, sobald sich die Quelle, AnotherProperty, ändert. Der OneWayToSource-Mode ist dann die Umkehrung, sodass AnotherProperty das Ziel ist und sich ändert, wenn Property geändert wird.
Und mit dem TwoWay-Mode hältst du beide Propertys synchron, dh sobald du eine davon änderst, wird die andere mitgeändert.

Hoffe ich konnte dir ein bisschen helfen 😁