Laden...

[gelöst] TwoWay-Bindung bei ComboBox

Erstellt von DiscMaster vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.073 Views
DiscMaster Themenstarter:in
316 Beiträge seit 2006
vor 14 Jahren
[gelöst] TwoWay-Bindung bei ComboBox

Sers zusammen!

Ich habe folgendes Problem:

Eine List<MyElement> wird über die ItemsSource-Eigenschaft an eine ComboBox gebunden.

Dann wird die Text-Eigenschaft eines Textfeldes an die SelectedItem-Eigenschaft gebunden.

MyElement ist eine Klasse mit dem Property "Name" (string), dieser String steht dann in dem Textfeld. Binding-Mode ist TwoWay.

Durch debugging habe ich festgestellt, dass das alles funktioniert, also wenn ich den Text im Textfeld ändere wird er auch übernommen, allerdings sehe ich diese Änderungen leider nicht in der ComboBox. Meine Überlegung ist, dass der BindingMode bei der ComboBox vielleicht anders sein müsste, das er standardmäßig auf OneTime eingestellt ist... Kann das sein? Oder wie beseitige ich das Problem?

Danke,
DiscMaster

"Flache Hierarchien schaffen! Das muss konkret nicht unbedingt etwas bedeuten, kommt aber immer sehr gut an."
Bernd Stromberg

3.430 Beiträge seit 2007
vor 14 Jahren

Hallo DiscMaster,

ich vermute mal dass das Problem daran liegt dass du in der MyElement-Klasse nicht das _:::

Wenn du das implementierst dann kannst du bei jeder Änderung der Name - Eigenschaft (im Setter) das PropertyChanged Event auslösen.
Somit wird auch die ComboBox darüber informiert.

Weiters wird es wohl notwendig sein dass du eine _:::

Gruss
Michael

DiscMaster Themenstarter:in
316 Beiträge seit 2006
vor 14 Jahren

Danke erstmal, ich habe beides beherzigt. Das Problem bleibt aber in gleicher Weiße bestehen...

Das PropertyChanged-Event wird gefeuert - allerdings sehe ich in der ComboBox keine Änderungen.

Ich weiß nicht ob diese Frage doof ist, aber...: Muss ich in der ObservableCollection das PropertyChange-Event von Hand abonieren? Und muss ich dann auch in der ComboBox das ItemEdited-Event abonieren?

"Flache Hierarchien schaffen! Das muss konkret nicht unbedingt etwas bedeuten, kommt aber immer sehr gut an."
Bernd Stromberg

U
36 Beiträge seit 2009
vor 14 Jahren

Hallo Discmaster,

könntest Du bitte etwas Code dazu posten? Eigentlich sollte das ziemlich leicht gehen und wenn wir Code sehen, würden wir das sicher schnell lösen können.

Ich kann mir vorstellen, dass da ein Binding-Mode falsch gesetzt ist oder der UpdateSourceTrigger im Binding der TextBox geändert werden muss.

DiscMaster Themenstarter:in
316 Beiträge seit 2006
vor 14 Jahren

Ok, hier eine kurze Erklärung damit euch die Namen nicht verwundern:

Ich arbeite an einem Tool zum schnellen erstellen und bearbeiten von Playlisten, sicherlich gibts das schon aber "selber macht schön" 😉 Das was jetzt entscheidend ist ist

  • die TextBox "txtAlias", zum bearbeiten des Playlist-Namens (nicht Dateiname)
  • Die ComboBox "cbxPlaylist", die an die ObservableCollection<Playlist> gebunden wird.
  • Playlist ist eine Mini-Klasse die Pfad und Namen der Wiedergabeliste enthält. Sie implementiert INotifyPropertyChanged korrekt, sprich, wenn ich das Playlist-Objekt einer ObservableCollection hinzufüge, ist der PropertyChanged-Event != null. Das Event wird auch ausgelöst, wenn ich den Text in txtAlias verändere und das Textfeld den Focus verliert, der neue Wert wird übernommen. Wer das Event allerdings aboniert hat kann ich nicht sagen, ich vermute nur das es die ObservableCollection ist...

Trotzdem sehe ich die Änderungen in der ComboBox nicht.

Hier noch einiger Code:

Das Markup von der ComboBox und dem Textfeld:


[...]
<ComboBox Name="cbxPlaylist" Margin="6,6,6,4" Grid.ColumnSpan="2" />
[...]
<TextBox Margin="3,3,6,4" Name="txtPlaylistName" Grid.Column="1" Grid.Row="1" Text="{Binding ElementName=cbxPlaylist, Path=SelectedItem.Alias, Mode=TwoWay}"/>
[...]

Im Konstruktor des Hauptfensters wird die ComboBox an die ObservableCollection gebunden:


cbxPlaylist.ItemsSource = settings.playlists; //settings.playlist : ObservableCollection<Playlist>

"Flache Hierarchien schaffen! Das muss konkret nicht unbedingt etwas bedeuten, kommt aber immer sehr gut an."
Bernd Stromberg

DiscMaster Themenstarter:in
316 Beiträge seit 2006
vor 14 Jahren

Keiner ne Antwort...?

"Flache Hierarchien schaffen! Das muss konkret nicht unbedingt etwas bedeuten, kommt aber immer sehr gut an."
Bernd Stromberg

T
18 Beiträge seit 2009
vor 14 Jahren

Hallo,

dieses Problem hatte ich neulich in einem ähnlichen Fall. Da hatte ich letztendlich "Mode=TwoWay" gelöscht, danach funktionierte alles wie ich wollte.

Woran das liegt, kann ich nur vermuten. Vermutlich versucht die TextBox bei Programmstart, in der ComboBox ein Item mit dem Wert der TextBox.Text - Property zu finden und auszuwählen. Da "Text" beim Start vermutlich leer ist, schlägt da irgendwas fehl und die Anzeige/Binding "zerschießt" sich.

Gruß, Tris

DiscMaster Themenstarter:in
316 Beiträge seit 2006
vor 14 Jahren

hmmm, aber wie konntest du feststellen das das Problem ohne TwoWay-Bindung gelöst war? Denn der Wert der dem Angezeigten in der ComboBox zugrunde liegt wird ja dann gar nicht mehr verändert (oder hast du das dann "von Hand" gemacht?)

"Flache Hierarchien schaffen! Das muss konkret nicht unbedingt etwas bedeuten, kommt aber immer sehr gut an."
Bernd Stromberg

T
18 Beiträge seit 2009
vor 14 Jahren

Hallo,
habe das mal in Grundzügen nachgebaut, bei mir funktioniert es.

Mein "SongModel" - speichert einfach nur einen Titel:


    public class SongModel : ViewModelBase
    {
        private string _title;
        public string Title
        {
            get { return _title; }
            set
            {
                _title = value;
                NotifyPropertyChanged("Title");
            }
        }


        public SongModel(string title)
        {
            Title = title;
        }
    }

Hier die Codebehind-Datei von Window1:


    public partial class Window1 : Window
    {
        public ObservableCollection<SongModel> SongCollection { get; set; }

        public Window1()
        {
            InitializeComponent();

            SongCollection = new ObservableCollection<SongModel>();

            SongCollection.Add(new SongModel("Song 1"));
            SongCollection.Add(new SongModel("Song 2"));
            SongCollection.Add(new SongModel("Song 3"));
 
            comboBox1.ItemsSource = SongCollection;
        }
}

Und in der xaml - Datei steht dann u.a. folgendes:


        <ComboBox Height="23" Margin="12,12,12,0" Name="comboBox1" VerticalAlignment="Top" 
                  IsReadOnly="True" IsSynchronizedWithCurrentItem="True"
                  ItemsSource="{Binding}"
                  DisplayMemberPath="Title"/>
        <TextBox Margin="12,101,12,0" Name="textBox1" Height="23" VerticalAlignment="Top" 
                 Text="{Binding SelectedItem.Title, ElementName=comboBox1, UpdateSourceTrigger=PropertyChanged}"/>

Das "ViewModelBase" der SongModel - Klasse kommt von Cinch. Ich war einfach zu faul, INotifyPropertyChanged zu implementieren 😉

Gruß, Tris

DiscMaster Themenstarter:in
316 Beiträge seit 2006
vor 14 Jahren

BINGO!

Die DisplayMemberPath-Eigenschaft in der ComboBox hat bei mir gefehlt. Eingebunden - und etz gehts!

Ganz großes Dankeschön! (Endlich mal wieder ein Erfolgserlebnis 😉)

Gruß DiscMaster

"Flache Hierarchien schaffen! Das muss konkret nicht unbedingt etwas bedeuten, kommt aber immer sehr gut an."
Bernd Stromberg