Laden...

MVVM (Visual Basic) - Combobox aktualisiert sich nicht?

Erstellt von _Cashisclay vor 6 Jahren Letzter Beitrag vor 6 Jahren 6.070 Views
_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren
MVVM (Visual Basic) - Combobox aktualisiert sich nicht?

Servus in die Runde..

Eventuell kann mir jemand fix weiterhelfen ich versuche eine Combobox Eingabe zu verändern.

Beim Laden (Inhalt) der Combobox funktioniert seltsamerweise alles einwandfrei.

Beispiel :

Property im ViewModel :


    Public Property Lieferschein_Text As String
        Get
            Return _Lieferschein_Text
        End Get
        Set(value As String)
            _Lieferschein_Text = value
            PropertyChange("Lieferschein_Text")
        End Set
    End Property

Ladevorgang :


If Not IsDBNull(DataRow.Item("Lieferschein")) Then ViewModel.Lieferschein_Text = DataRow.Item("Lieferschein")

Lieferschein Inhalt wird korrekt angezeigt.

ViewModel_PropertyChanged Event :


Case "Lieferschein_Text"

                    If ViewModel.Lieferschein_Text = "A" Then

                        ViewModel.Lieferschein_Text = ""

                    End If

Funktioniert nicht der Inhalt bleibt beim A

Kann mir jemand weiterhelfen?

Grüße

2.298 Beiträge seit 2010
vor 6 Jahren

Hast du denn schon mal mit dem Debugger geprüft, ob der Code überhaupt angesprochen wird?

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren

Hallo inflames2k!

Ja, hab ich und er wird auch durchlaufen.

Edit: in der Property steht dann auch der neue Wert drinne, aber die ComboBox hat immer noch den alten Wert.

3.170 Beiträge seit 2006
vor 6 Jahren

Hallo,

wie sieht denn das Binding aus?

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren
                        
<ComboBox Margin="1" IsEditable="True" ItemsSource="{Binding Lieferschein, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Lieferschein" SelectedIndex="{Binding Lieferschein_SelectedIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Text="{Binding Lieferschein_Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding IsEnabled}" IsTextSearchEnabled="False" IsSynchronizedWithCurrentItem="True">

                                    <ComboBox.ItemsPanel>

                                        <ItemsPanelTemplate>

                                            <VirtualizingStackPanel VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling"/>

                                        </ItemsPanelTemplate>

                                    </ComboBox.ItemsPanel>

                                </ComboBox>

 

Ich hab auch schon versucht die ItemSource zu aktualisieren (klappt auch) und den SelectedIndex auf den Eintrag zu wechseln, trotzdem bleibt in dem Fall (alles via Quellcode) der Inhalt veraltet.

Grüße

Edit : IsSynchronizedWithCurrentItem="True" hab ich gestern erst beim rumprobieren hinzugefügt.

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren

Jemand eine Idee?

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren

Es scheint so .. das er die Ansicht nicht ändert wenn man die Variable im PropertyChanged Event verändern möchte, wenn ich das ganze über einen extra Button steuer .. funktioniert es.

Jemand eine Idee warum?

1.040 Beiträge seit 2007
vor 6 Jahren

Wann genau änderst du denn jetzt den Wert?

3.170 Beiträge seit 2006
vor 6 Jahren

Hallo,

das hatte ich gar nicht gesehen, dass das im PropertyChanged passiert...
Ich denke das passiert, weil Du die selbe Property während ihres Changed-Events nochmal änderst, wird diese Änderung aus Sicherheitsgründen ignoriert (habe mir den Code von .NET diesbezügl. noch nicht angeschaut). Sonst könntest Du da z.B. leicht eine Endlosschleife aus PropertyChanged-Events bauen.

Warum wiollst Du das eigentlich im PropertyChanged überprüfen, und nicht direkt im Setter? Dann könnte sowas nicht passieren...

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren

Ich probiere es aktuell im PropertyChanged Event an dieser Stelle :

                Case "Lieferschein_Text"

                    ViewModel.Kundennummer_Value = ViewModel.Kundennummer_Text
                    ViewModel.Lieferschein_Value = ViewModel.Lieferschein_Text

                    ' --- Bereinigung --- '

                    ViewModel.Lieferschein_Datum = ""

                    ' --- Individuelle Eingabe --- '

                    set_ComboBox_Kundennummer_Lieferschein()

                    If ViewModel.Lieferschein_Text = "A" Then

                        ViewModel.Lieferschein_Text = "Ohne"

                    End If

Im Setter hatte ich es schon versucht und eben auch noch einmal .. hatte auch nicht funktioniert.

    Public Property Lieferschein_Text As String
        Get
            Return _Lieferschein_Text
        End Get
        Set(value As String)

            If value = "A" Then

                value = "B"

            End If

            _Lieferschein_Text = value
            PropertyChange("Lieferschein_Text")
        End Set
    End Property
D
985 Beiträge seit 2014
vor 6 Jahren

Zeig bitte das ViewModel mit allen Eigenschaften die an der ComboBox gebunden sind.

57 Beiträge seit 2012
vor 6 Jahren

= und == sind nicht dasselbe! In einer if-Anweisung musst du == verwenden zum vergleichen.

OO gibts seit Platon - hatte der auch C#?

D
985 Beiträge seit 2014
vor 6 Jahren

@CWolle

Aber nicht in VB.net 😉

57 Beiträge seit 2012
vor 6 Jahren

ich bin doch in einem C#-Forum, oder?
Das Code-Fenster ist auch mit 'C#-Code' beschriftet! Versteh ich irgendwas falsch?

OO gibts seit Platon - hatte der auch C#?

D
985 Beiträge seit 2014
vor 6 Jahren

Also für mich ist das VB.NET Code


    Public Property Lieferschein_Text As String
        Get
            Return _Lieferschein_Text
        End Get
        Set(value As String)

            If value = "A" Then

                value = "B"

            End If

            _Lieferschein_Text = value
            PropertyChange("Lieferschein_Text")
        End Set
    End Property

Hinweis von gfoidl vor 6 Jahren

Genau, daher braucht das auch nicht weiter vertieft werden.

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren

Hallo Sir Rufo!

Sorry für die späte Antwort hatte leider kaum Rechnerzugang am Wochenende.

Hier mal das ViewModel mit allen Eigenschaften die an diese ComboBox gebunden sind :



    Public Property Lieferschein As System.Data.DataTable
        Get
            Return _Lieferschein
        End Get
        Set(value As System.Data.DataTable)
            _Lieferschein = value
            PropertyChange("Lieferschein")
        End Set
    End Property

    Public Property Lieferschein_SelectedIndex As Integer
        Get
            Return _Lieferschein_SelectedIndex
        End Get
        Set(value As Integer)
            _Lieferschein_SelectedIndex = value
            PropertyChange("Lieferschein_SelectedIndex")
        End Set
    End Property

    Public Property Lieferschein_Text As String
        Get
            Return _Lieferschein_Text
        End Get
        Set(value As String)
            _Lieferschein_Text = value
            PropertyChange("Lieferschein_Text")
        End Set
    End Property


Hab jetzt mal den Code nochmal als nicht C# Code gekennzeichnet ... Sorry!

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren

Hab jetzt mal die PropertyChangedCallback Funktion versucht, er setzt zwar den Wert korrekt, aber der ComboBox Inhalt verändert sich halt einfach nicht, als wenn die sich nicht aktualsieren möchte..

D
985 Beiträge seit 2014
vor 6 Jahren

Was du aktuell machst ist in die Eingabe des Benutzers einzugreifen.

Das Control bekommt auf einer Eigenschaft einen geänderten Wert zugewiesen und ruft die Bindings-Logik auf. Während dessen werden allerdings Änderungen an dieser Eigenschaft nicht angenommen weil es sonst zu unendlich rekursiven Aufrufen kommen könnte.

Der Eingriff muss also vor oder nach dem Aufruf des Bindings erfolgen.

Vor dem Binding kommt man z.B. über eine AttachedProperty an das Control.
Nach dem Binding erreicht man durch das Starten eines Tasks.

Ich würde mich hier wohl für eine AttachedProperty entscheiden.

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren

Hast du denn ein Beispiel dazu? Bzw. hast du das in der Richtung schon mal gemacht und weißt das es so funktionieren würde?

D
985 Beiträge seit 2014
vor 6 Jahren

Nicht mit einer ComboBox aber z.B. habe ich damit einer TextBox beigebracht nur Zahlen zu akzeptieren. Dort greift man auch in die Benutzereingabe ein.

Über die AttachedProperty kann man Logik aus dem ViewModel mit dem Control verbinden ohne dass beide sich kennen müssen und genau das willst du ja hier wohl auch machen.

5.657 Beiträge seit 2006
vor 6 Jahren

Also ich verstehe die Anforderungen so, daß der Anzeigetext eines Objektes in Abhängigkeit von anderen Eigenschaften gesetzt werden soll.
Das wäre dann Aufgabe des Models bzw. des ViewModels. Aber nicht der View.

Aber das Problem bzw. die Unklarheit fängt schon bei der Deklaration der ComboBox-Eigenschaften an:

                        
<ComboBox Margin="1" IsEditable="True" ItemsSource="{Binding Lieferschein, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Lieferschein" SelectedIndex="{Binding Lieferschein_SelectedIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Text="{Binding Lieferschein_Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding IsEnabled}" IsTextSearchEnabled="False" IsSynchronizedWithCurrentItem="True">

Warum wird bspw. der DisplayMemberPath auf die Eigenschaft gesetzt, die auch gleichzeitig die ItemsSource ist?

Mir ist wirklich nicht klar, was genau die konkreten Anforderungen sind. Aber die Definition der ComboBox ergibt wirklich keinen Sinn.

Beispiele für die Bindung an ItemsControls/ListViews/ComboBoxen gibt es in [Artikel] MVVM und DataBinding

Weeks of programming can save you hours of planning

D
985 Beiträge seit 2014
vor 6 Jahren

Die Items in ItemsSource haben eine Eigenschaft mit dem Namen Lieferschein. Ist also völlig ok.

IsEditable auf true lässt erwarten, dass hier bei der ComboBox eine freie Eingabe zugelassen werden soll wie bei einer TextBox.

Unsinnig - im Sinne von überflüssig - ist das Binden der ItemsSource mit TwoWay und PropertyChanged. Frisst aber auch kein Brot.

Natürlich ist es Aufgabe des ViewModels die Logik bereitzustellen wenn diese von anderen Eigenschaften im ViewModel abhängig ist, aber aufgrund des Timings muss man entweder in das Control selber eingreifen oder einen asynchronen Aufruf tätigen.

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren

Das klingt so als wenn das Sinn macht mit dem AttachedProperty.. konnte aber bis jetzt noch keinen Erfolg verbuchen.

D
985 Beiträge seit 2014
vor 6 Jahren

Hier mal eine Lösung in C#

Definition der AttachedProperty
(wer sich an der Begrifflichkeit Behavior stört, ersetze das bitte in Gedanken durch EgonKarlSeineFrauIhreGedöns)


using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace mc119350.WpfApp.Behavior
{
    public interface ITextInterception
    {
        bool ShouldChangeText(string value, out string newValue);
    }

    public static class ComboBoxInterceptor
    {
        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TextInterceptionProperty =
            DependencyProperty.RegisterAttached(
                "TextInterception",
                typeof(ITextInterception),
                typeof(ComboBoxInterceptor),
                new PropertyMetadata(null, TextInterceptionChanged));

        public static void SetTextInterception(ComboBox obj, ITextInterception value)
        {
            obj.SetValue(TextInterceptionProperty, value);
        }

        public static ITextInterception GetTextInterception(ComboBox obj)
        {
            return obj.GetValue(TextInterceptionProperty) as ITextInterception;
        }

        static void TextInterceptionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var obj = d as ComboBox;
            if (e.OldValue == null && e.NewValue != null)
            {
                obj.PreviewTextInput += ComboBox_PreviewTextInput;
            }
            if (e.OldValue != null && e.NewValue == null)
            {
                obj.PreviewTextInput -= ComboBox_PreviewTextInput;
            }
        }

        static void ComboBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            var obj = sender as ComboBox;
            var interceptor = GetTextInterception(obj);
            string newText;
            if (interceptor.ShouldChangeText(e.Text,out newText))
            {
                e.Handled = true;
                obj.Text = newText;
            }
        }

    }
}

Hier das ViewModel


using GalaSoft.MvvmLight;
using mc119350.WpfApp.Behavior;
using System.Collections.ObjectModel;

namespace mc119350.WpfApp.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
            Lieferschein = new ObservableCollection<LieferscheinViewModel>(
                new System.Collections.Generic.List<LieferscheinViewModel>
                {
                    new LieferscheinViewModel{ Lieferschein = "1234" },
                    new LieferscheinViewModel{ Lieferschein = "12345" },
                    new LieferscheinViewModel{ Lieferschein = "123456" },
                }
            );

            TextInterception = new TextInterceptionImpl();
        }

        class TextInterceptionImpl : ITextInterception
        {
            public bool ShouldChangeText(string value, out string newValue)
            {
                if (value == "A")
                {
                    newValue = "B";
                    return true;
                }
                newValue = string.Empty;
                return false;
            }
        }

        ObservableCollection<LieferscheinViewModel> _lieferschein;
        string _lieferschein_Text;
        int _lieferschein_SelectedIndex;
        bool _isEnabled = true;
        ITextInterception _textInterception;

        public ITextInterception TextInterception
        {
            get => _textInterception;
            set => Set(ref _textInterception, value);
        }

        public ObservableCollection<LieferscheinViewModel> Lieferschein
        {
            get => _lieferschein;
            set => Set(ref _lieferschein, value);
        }

        public string Lieferschein_Text
        {
            get => _lieferschein_Text;
            set => Set(ref _lieferschein_Text, value);
        }
        public int Lieferschein_SelectedIndex
        {
            get => _lieferschein_SelectedIndex;
            set => Set(ref _lieferschein_SelectedIndex, value);

        }
        public bool IsEnabled
        {
            get => _isEnabled;
            set => Set(ref _isEnabled, value);
        }

    }

    public class LieferscheinViewModel : ViewModelBase
    {
        string _lieferschein;

        public string Lieferschein { get => _lieferschein; set => Set(ref _lieferschein, value); }

    }
}

und zu guter letzt die View


<Window x:Class="mc119350.WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:behavior="clr-namespace:mc119350.WpfApp.Behavior"
        xmlns:local="clr-namespace:mc119350.WpfApp"
        mc:Ignorable="d"
        DataContext="{Binding Source={StaticResource Locator}, Path=Main}"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition />
        </Grid.RowDefinitions>
        <ComboBox Grid.Row="0"
            behavior:ComboBoxInterceptor.TextInterception="{Binding TextInterception}"
            ItemsSource="{Binding Lieferschein}" 
            DisplayMemberPath="Lieferschein" 
            SelectedIndex="{Binding Lieferschein_SelectedIndex,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
            Text="{Binding Lieferschein_Text,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
            IsEnabled="{Binding IsEnabled}"
            IsTextSearchEnabled="True" 
            IsEditable="True"
            Margin="1"/>
    </Grid>
</Window>

3.170 Beiträge seit 2006
vor 6 Jahren

Hallo,

Im Setter hatte ich es schon versucht und eben auch noch einmal .. hatte auch nicht funktioniert.

Das kommt mir seltsam vor...
Ich muss jetzt doch mal nachfragen: Bist Du sicher, dass Dein VM auch tatsächlich INotifyPropertyChanged implementiert, oder nur das PropertyChanged-Event zur Verfügung stellt?

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

D
985 Beiträge seit 2014
vor 6 Jahren

Im Setter hatte ich es schon versucht und eben auch noch einmal .. hatte auch nicht funktioniert.
Das kommt mir seltsam vor...

Probier es einfach mal aus

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren

Also so richtig krieg ich es nicht hin ..

Woher soll denn TextInterception wissen wann sich der Lieferschein_Text ändert?

D
985 Beiträge seit 2014
vor 6 Jahren

Ich bin natürlich davon ausgegangen, dass du immer noch das erreichen möchtest:

ich versuche eine Combobox Eingabe zu verändern

Und genau da setze ich an: Bei der Eingabe in der ComboBox.

Wenn dem nicht mehr so ist, dann musst du das nochmal genauer spezifizieren.

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren

Möchte ich auch allerdings verändert sich in meiner TextInterception Property nichts bei dem Binding..

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren

Aus meiner Sicht brauch ich doch nur das um zu prüfen ob ich die Eingabe im Vorfeld verändern kann :

Hier mal eine Lösung in C#

Definition der AttachedProperty
(wer sich an der Begrifflichkeit Behavior stört, ersetze das bitte in Gedanken durch EgonKarlSeineFrauIhreGedöns)

  
using System.Windows;  
using System.Windows.Controls;  
using System.Windows.Input;  
  
namespace mc119350.WpfApp.Behavior  
{  
    public interface ITextInterception  
    {  
        bool ShouldChangeText(string value, out string newValue);  
    }  
  
    public static class ComboBoxInterceptor  
    {  
        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...  
        public static readonly DependencyProperty TextInterceptionProperty =  
            DependencyProperty.RegisterAttached(  
                "TextInterception",  
                typeof(ITextInterception),  
                typeof(ComboBoxInterceptor),  
                new PropertyMetadata(null, TextInterceptionChanged));  
  
        public static void SetTextInterception(ComboBox obj, ITextInterception value)  
        {  
            obj.SetValue(TextInterceptionProperty, value);  
        }  
  
        public static ITextInterception GetTextInterception(ComboBox obj)  
        {  
            return obj.GetValue(TextInterceptionProperty) as ITextInterception;  
        }  
  
        static void TextInterceptionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)  
        {  
            var obj = d as ComboBox;  
            if (e.OldValue == null && e.NewValue != null)  
            {  
                obj.PreviewTextInput += ComboBox_PreviewTextInput;  
            }  
            if (e.OldValue != null && e.NewValue == null)  
            {  
                obj.PreviewTextInput -= ComboBox_PreviewTextInput;  
            }  
        }  
  
        static void ComboBox_PreviewTextInput(object sender, TextCompositionEventArgs e)  
        {  
            var obj = sender as ComboBox;  
            var interceptor = GetTextInterception(obj);  
            string newText;  
            if (interceptor.ShouldChangeText(e.Text,out newText))  
            {  
                e.Handled = true;  
                obj.Text = newText;  
            }  
        }  
  
    }  
}  
  

Hier das ViewModel

  
using GalaSoft.MvvmLight;  
using mc119350.WpfApp.Behavior;  
using System.Collections.ObjectModel;  
  
namespace mc119350.WpfApp.ViewModel  
{  
    public class MainViewModel  
    {  
        public MainViewModel()  
        {  
            TextInterception = new TextInterceptionImpl();  
        }  
  
        class TextInterceptionImpl : ITextInterception  
        {  
            public bool ShouldChangeText(string value, out string newValue)  
            {  
                if (value == "A")  
                {  
                    newValue = "B";  
                    return true;  
                }  
                newValue = string.Empty;  
                return false;  
            }  
        }  
  
        string _lieferschein_Text;  
        ITextInterception _textInterception;  
  
        public ITextInterception TextInterception  
        {  
            get => _textInterception;  
            set => Set(ref _textInterception, value);  
        }  
  
        public string Lieferschein_Text  
        {  
            get => _lieferschein_Text;  
            set => Set(ref _lieferschein_Text, value);  
        }  
  
    }  
  
}  
  

und zu guter letzt die View

  
<Window x:Class="mc119350.WpfApp.MainWindow"  
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
        xmlns:behavior="clr-namespace:mc119350.WpfApp.Behavior"  
        xmlns:local="clr-namespace:mc119350.WpfApp"  
        mc:Ignorable="d"  
        DataContext="{Binding Source={StaticResource Locator}, Path=Main}"  
        Title="MainWindow" Height="350" Width="525">  
    <Grid>  
        <Grid.RowDefinitions>  
            <RowDefinition Height="Auto"/>  
            <RowDefinition />  
        </Grid.RowDefinitions>  
        <ComboBox Grid.Row="0"  
            behavior:ComboBoxInterceptor.TextInterception="{Binding TextInterception}"  
            Text="{Binding Lieferschein_Text,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"  
            IsEditable="True"  
            Margin="1"/>  
    </Grid>  
</Window>  
  

Und das habe ich auch versucht so in VB.net umzusetzen..

3.170 Beiträge seit 2006
vor 6 Jahren

Hallo,

Probier es einfach mal aus

Das habe ich gemacht. Allerdings glaube ich, dass ich die Frage immer noch missverstehe.

Tatsche ist, das Binding für den angezeigten Text in den Combobox-Items läuft über die Elemente der ItemsSource und den DisplayMemberName.
Das Binding für den Text, der in der (zugeklappten) Combobox angezeigt wird, kommt über das ViewModel. In diese gebundene Property geht auch der Text, den man in die Combo tippt.

Das funktioniert auch alles wie ich mir das vorgestellt habe. Ändert man die Property im MainViewModel z.B. über einen Task, wird das auch richtig angezeigt. Ändert amn den Wert in einem gebundenen Item, wird diese ebenfalls korrekt aktualisiert (wenn das Item INPC implementiert).

Zwischen beiden Werten besteht bezügl. des Bindings erst mal keine Kopplung, will man eine haben, muss man sie implemetieren.

@_Cashisclay
Ich glaube, der Knackpunkt liegt aber ganz woanders:
Wenn man Text in die Combo tippt, wird die Source aktualisiert - während dieser Aktualisierung ist aber die Gegenrichtung - View aktualisieren aus der Source - für dieses Element unterdrückt. Eine Änderung des getippten Textes ist auf die Art nicht möglich - dazu brauchst Du dann sowas wie von Sir Rufo vorgeschlagen.

Falls das noch nicht hilft:
Damit wir hier nicht alle aneinander vorbeireden, solltest Du nochmal genau beschreiben, was Du vorhast.
Aus Deinem ersten Post:

If Not IsDBNull(DataRow.Item("Lieferschein")) Then ViewModel.Lieferschein_Text = DataRow.Item("Lieferschein")

Wann und durch welche Aktion wird dieser Code denn ausgeführt?
Wann wird Lieferschein_Text noch geändert, und durch welche Benutzeraktion?
Was stellst Du Dir als Ergebnis vor, und was passiert stattdessen?
Kannst Du das versuchen möglichst genau zu beschreiben, denn bisher ist das (zumindest für mich) immer noch etwas undurchsichtig.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

D
985 Beiträge seit 2014
vor 6 Jahren

@_Cashisclay
Also bei meinem Beispiel passiert eigentlich genau das was du mMn gewünscht hast:

Tippt man in die ComboBox A ein dann erscheint dort ein B.

FullQuotes sind hier nicht gern gesehen, weil sie auch keinen wirklichen Sinn ergeben

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren

@Sir Rufo : Es ist kein FullQuote, habe einige deiner Zeilen gelöscht, die mMn nicht relevant waren.. In jedem Fall muss ich ja irgendwas falsch machen, weil bei mir funktioniert es nicht..

@MarsStein :

Ich habe vor den Inhalt von Text Property der ComboBox zu ändern :
Bedeutet wenn der User (Beispiel) A eintippt möchte ich daraus automatisch ein B machen.


If Not IsDBNull(DataRow.Item("Lieferschein")) Then ViewModel.Lieferschein_Text = DataRow.Item("Lieferschein")

Diese Zeile stammte aus dem PropertyChanged Event ..

Beispiel :

Select Case e.PropertyName

Case "Lieferschein_Text"

IF ViewModel.Lieferschein_Text = "A" THEN

ViewModel.Lieferschein_Text = "B"

END IF

Wie man das lösen könnte, kam ja bereits von Sir Rufo, allerdings krieg ich es in VB.NET noch nicht hin

D
985 Beiträge seit 2014
vor 6 Jahren

Was konkret bekommst du denn nicht hin?

Du hast nur das ViewModel geändert, dann hätte im Quote auch nur das ViewModel gereicht. So sieht man den Wald vor lauter Bäumen nicht.

Und wenn man etwas ändert, dann ist es auch kein Zitat (Quote) mehr.

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren

Deinen Quellcode quasi in VB.net zu übertragen, weil wenn ich eine Eingabe in der Combobox tätige er nicht mal in das TextInterception springt..

D
985 Beiträge seit 2014
vor 6 Jahren

Eine Suche bei Tante G nach c# to vb.net ergibt als ersten Treffer

Telerik: Code Converter

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren

Das kannst du aber nicht 1 zu 1 so übernehmen, außerdem hab ich Codeschnipsel die mir nicht bekannt vor kamen damit schon übersetzt, wie gesagt es funktioniert ja nicht.

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren

Denke mal im ViewModel hab ich irgendwas falsch gemacht

Public Class ComboBoxTry

    Public Interface ITextInterception

        Function ShouldChangedText(value As String, newValue As String) As Boolean

    End Interface

    Public Shared ReadOnly TextInterceptionProperty As DependencyProperty = DependencyProperty.RegisterAttached("TextInterception", GetType(ITextInterception), GetType(ComboBoxTry),
                                                                                                     New FrameworkPropertyMetadata(Nothing,
                                                                                                                                   New PropertyChangedCallback(AddressOf ComboBox_TextChanged)))

    Public Shared Sub SetTextInterception(obj As ComboBox, value As ITextInterception)

        obj.SetValue(TextInterceptionProperty, value)

    End Sub

    Public Shared Function GetTextInterception(obj As ComboBox) As ITextInterception

        Return TryCast(obj.GetValue(TextInterceptionProperty), ITextInterception)

    End Function

    Private Shared Sub ComboBox_TextChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)

        Dim ComboBox As ComboBox = d

        If ComboBox.Text = "C" Then

            AddHandler ComboBox.PreviewTextInput, AddressOf ComboBox_PreviewTextInput

        End If

    End Sub

    Private Shared Sub ComboBox_PreviewTextInput(sender As Object, e As TextCompositionEventArgs)



    End Sub

End Class

Imports WpfApplication2.ComboBoxTry

Public Class ViewModel

    Implements System.ComponentModel.INotifyPropertyChanged

    Sub New()

        Dim TextInterception As New TextInterceptionImpl

    End Sub




    Class TextInterceptionImpl

        Implements ITextInterception

        Public Function ShouldChangedText(value As String, newValue As String) As Boolean Implements ComboBoxTry.ITextInterception.ShouldChangedText

            If value = "A" Then

                newValue = "B"

                Return True

            End If

            newValue = String.Empty

            Return False

        End Function

    End Class

    Private _TextInterception As ITextInterception

    Public Property TextInterception As ITextInterception
        Get
            Return _TextInterception
        End Get
        Set(value As ITextInterception)
            _TextInterception = value
            PropertyChange("TextInterception")
        End Set
    End Property

    Private _Lieferschein_Text

    Public Property Lieferschein_Text As String
        Get
            Return _Lieferschein_Text
        End Get
        Set(value As String)
            _Lieferschein_Text = value
            PropertyChange("Lieferschein_Text")
        End Set
    End Property


#Region "Interface"
    Private Sub PropertyChange(ByVal Name As String)
        RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs(Name))
    End Sub

    Public Event PropertyChanged(sender As Object, e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
#End Region

End Class

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication2"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        
        <ComboBox local:ComboBoxTry.TextInterception="{Binding TextInterception}" Text="{Binding Lieferschein_Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEditable="True"/>
        
    </Grid>
</Window>

EDIT: hab jetzt nicht versucht die Variable direkt zu beeinflussen, hab erstmal nur versucht mit Breakpoints zu gucken ob er in die Funktionen reinspringt

709 Beiträge seit 2008
vor 6 Jahren

ComboBox_PreviewTextInput ist bei dir leer.

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren

Ich weiß, aber das sollte ja nicht daran stören in die Funktion zu springen und das macht er eben erst gar nicht 😕

mMn springt er nicht mal in die ComboBox_TextChanged, weil local:ComboBoxTry.TextInterception="{Binding TextInterception}" überhaupt kein Bezug hat zur Text Property

D
985 Beiträge seit 2014
vor 6 Jahren

Deine ComboBoxTry Klasse ist falsch.

Du musst dich am Event ComboBox.PreviewTextInput registrieren/abmelden und zwar immer dann, wenn sich die AttachedProperty ändert.

Pseudo-Code

OldValue == null && NewValue != null => Subscribe event
OldValue != null && NewValue == null => Unsubscribe event

Du hängst dich an den Event, wenn in ComboBox.Text ein D steht.

Steht da also kein D warum denkst du sollte dort etwas passieren?

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren

Er kommt ja nicht mal in das ComboBox_TextChanged Event.. ich kann mich so oder so nicht aktuell mit dem ComboBox_PreviewTextInput Event auseinandersetzen 😮

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren

Okay hab es endlich hinbekommen ..

Danke für das Beispiel Sir Rufo!

Endlich ein Erfolgserlebnis nach 3 Tagen .. sorry wenn ich manchmal ein wenig seltsam geantwortet habe, aber mittlerweile hatte ich echt schlechte Laune wegen dem ganzen, ich versuch das ganze jetzt nachzuvollziehen, dann bastel ich das auf mein Projekt um und teile das Ergebnis nochmal für alle in VB.NET ..

Danke nochmal für das Beispiel.

_
_Cashisclay Themenstarter:in
277 Beiträge seit 2014
vor 6 Jahren

Servus Sir Rufo,

ich bastel momentan noch mit dem Attached Property.. allerdings brauch ich einige Variablen aus meinem ViewModel und als ich dann ein wenig rumprobiert habe.. kam irgendwann die Frage in mir auf, warum man nicht einfach gleich das PreviewTextInput Event von der ComboBox nutzt, wäre doch wesentlich einfacher oder? 😄

Grüße