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
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 |
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.
Hallo,
wie sieht denn das Binding aus?
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
<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.
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?
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
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
Zeig bitte das ViewModel mit allen Eigenschaften die an der ComboBox gebunden sind.
= und == sind nicht dasselbe! In einer if-Anweisung musst du == verwenden zum vergleichen.
OO gibts seit Platon - hatte der auch C#?
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#?
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
Genau, daher braucht das auch nicht weiter vertieft werden.
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!
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..
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 Task
s.
Ich würde mich hier wohl für eine AttachedProperty
entscheiden.
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?
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.
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
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.
Das klingt so als wenn das Sinn macht mit dem AttachedProperty.. konnte aber bis jetzt noch keinen Erfolg verbuchen.
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>
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
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
Also so richtig krieg ich es nicht hin ..
Woher soll denn TextInterception wissen wann sich der Lieferschein_Text ändert?
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.
Möchte ich auch allerdings verändert sich in meiner TextInterception Property nichts bei dem Binding..
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..
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
@_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
@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
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.
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..
Eine Suche bei Tante G nach c# to vb.net
ergibt als ersten Treffer
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.
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
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
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?
Er kommt ja nicht mal in das ComboBox_TextChanged Event.. ich kann mich so oder so nicht aktuell mit dem ComboBox_PreviewTextInput Event auseinandersetzen 😮
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.
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