mayho33
Goto Top

C-Sharp WPF Binding TextBox.Text und Property MVVM

Hi @ All!

Komplett neu auf dem Gebiet WPF komme irgendwie mit dem Binding Textbox.Text zu Property und umgekehrt nicht zurecht. Es wird weder das Property aktualisiert beim Ändern des Textes in der Textbox, noch umgekehrt.

Meine Textbox ist im Xaml so definiert:

<TextBox x:Name="textBox_Test" Height="19" TextWrapping="Wrap" TextAlignment="Center" VerticalAlignment="Bottom" Width="34" Margin="0,0,0,10"  
         Text="{Binding Path=Test, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>  

Das Property ist so definiert:

public class BaseCalc : INotifyPropertyChanged
{
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(String property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }

        private double _Test;
        public double Test
        {
            get
            {
                return this._Test;
            }
            set
            {
                if (value != this._Test)
                {
                    this._Test = value;
                    OnPropertyChanged("Test");  
                }
                //OnPropertyChanged("Test"); 
            }
        }
}

Testweise habe ich das Property aus der Main heraus geändert was natürlich funktioniert, das PropertyChanged ist aber immer null (??).

Hat jemand einen Tipp. Eventuell ein Beispiel? ich habe keine Ahnung warum es nicht funktioniert.

Danke für die Hilfe!

Mayho

Content-Key: 300449

Url: https://administrator.de/contentid/300449

Ausgedruckt am: 29.03.2024 um 05:03 Uhr

Mitglied: colinardo
colinardo 31.03.2016 aktualisiert um 14:23:07 Uhr
Goto Top
Hallo Mayho,
hier mal ein Beispiel wie man es machen kann:

Man registriert eine DependencyProperty vergibt Ihr einen Namen definiert deren Typ, und erstellt dann eine Property mit dem selben Namen den man der DependencyProperty vergeben hat.
Im XAML Code vergibt man dann dem Window einen Namen z.B. MyControl und gibt in der Text-Eigenschaft der Textbox dann dieses Binding an:
Text="{Binding ElementName=MyControl, Path=testProperty,Mode=TwoWay}"

Hier noch die kompletten Bestandteile des Beispiels:

back-to-topXAML Code
<Window x:Class="PropertyBinding.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:local="clr-namespace:PropertyBinding"  
        mc:Ignorable="d"  
        Title="Property Binding" Height="133.734" Width="222.38" Name="MyControl">  
    <Grid>
        <TextBox x:Name="txt1" Height="23" Margin="10,10,10,0" TextWrapping="Wrap" VerticalAlignment="Top" Text="{Binding ElementName=MyControl, Path=testProperty,Mode=TwoWay}"/>  
        <Button x:Name="btnGetProp" Content="Get Property Value" Margin="10,38,10,0" VerticalAlignment="Top" RenderTransformOrigin="0.525,0.532" Click="btnGetProp_Click"/>  
        <Button x:Name="btnWriteProp" Content="Write Property Value" Margin="10,74,10,0" VerticalAlignment="Top" RenderTransformOrigin="0.525,0.532" Click="btnWriteProp_Click"/>  
    </Grid>
</Window>

back-to-topCodeBehind:
using System.Windows;
namespace PropertyBinding
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        public static DependencyProperty _testProperty = DependencyProperty.Register("testProperty", typeof(string), typeof(MainWindow));  

        public string testProperty {
            get
            {
                return (string)GetValue(_testProperty);
            }
            set
            {
                SetValue(_testProperty, value);
            }
        }
        private void btnGetProp_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(testProperty);
        }

        private void btnWriteProp_Click(object sender, RoutedEventArgs e)
        {
            testProperty = "Das ist ein Demotext";  
        }
    }
}
Siehe auch:
How to data bind to property in WPF

Grüße Uwe
Mitglied: mayho33
mayho33 31.03.2016 aktualisiert um 16:17:01 Uhr
Goto Top
Hi Uwe!

Danke für das ausführliche Beispiel. Vor etwa 10 Minuten habe ich die Lösung eher per Zufall gefunden. Das Problem lag daran, dass ich meine Properties in einer eigenen Klasse definiert hatte. Sobald ich aber eine Partial Class daraus gemacht habe sprich...

public partial class MainWindow : Window
{
...
...
}

... hat es funktioniert.

Ich hänge dafür aber nun woanders. Wenn du also ev. auch dafür einen Tipp hättest:

Ich habe eine ComboBox. Im XAML definiere ich gleich die Items und welches selected ist:

<ComboBox x:Name="comboBox_1" Height="19" VerticalAlignment="Top" Width="131">  
	<ComboBoxItem Content="100"/>  
        <ComboBoxItem Content="99,5 / 0,5" IsSelected="True"/>  
        <ComboBoxItem Content="86,5 / 13,5"/>  
</ComboBox>

Das funktioniert soweit wunderbar, wil ich aber ein Binding auf ein Property darauf legen, bleibt die ComboBox leer und das Property wird erst befüllt, nachdem ich im Window ein Item ausgewählt habe.

mein Code dazu

XAML:
<ComboBox x:Name="comboBox_1" Height="19" VerticalAlignment="Top" Width="131">  
	<ComboBoxItem Tag="100" Content="100"/>  
        <ComboBoxItem Tag="99" Content="99,5 / 0,5" IsSelected="True"/>  
        <ComboBoxItem Tag="86" Content="86,5 / 13,5"/>  
       <ComboBox.SelectedValue>
           <Binding Path="combo_currentValue" UpdateSourceTrigger="PropertyChanged"/>  
       </ComboBox.SelectedValue>
</ComboBox>

Property:
private string _combo_currentValue;
        public string combo_currentValue
        {
            get
            {
                return this._combo_currentValue;
            }
            set
            {

                if (this._combo_currentValue == value)
                {
                    return;
                }

                this._combo_currentValue = value;
                RaisePropertyChanged("combo_currentValue");  
            }
        }

Eventuell gleich ein 2te Frage dazu:

Wie kann ich über das Property gleich das entsprechende Item in der Combobox auswählen? wäre vermutlich mit einer List<> schlauer oder?


EDIT:

Mann, Mann, Mann! Soeben die Lösung (zumoindest tlw.) gefunden:
XAML:
<ComboBox x:Name="comboBox_1" Height="19" VerticalAlignment="Top" Width="131" ItemsSource="{Binding Path=combo}>  

Das Property ist nun ein List<> Property. im Window_Loaded habe ich das definiert:
comboBox_1.itemsSource = combo;
comboBox_1.SelectedIndex = 0;

Aber hat das dann noch was mit MVVM zu tun?? Wie kann ich das umsetzen? Stehe sowas von auf dem Schlauch. bool Durchblick = false

Danke!

Christian
Mitglied: colinardo
Lösung colinardo 31.03.2016 aktualisiert um 23:14:45 Uhr
Goto Top
Aber hat das dann noch was mit MVVM zu tun?? Wie kann ich das umsetzen?
So wie ich es oben gemacht habe kannst du der ItemsSource der ComboBox auch die Liste (List<string>) zuweisen. Geht hier im Test problemlos.
Für den aktuell ausgewählten Eintrag der Combobox kannst du das ebenfalls über eine weitere Property definieren. Bin da jetzt aber auch nicht so im Thema drin.

Die Möglichkeiten des Bindings für die SelectedN Einträge findest du auch hier erläutert
Difference between SelectedItem, SelectedValue and SelectedValuePath
Mitglied: mayho33
mayho33 06.04.2016 um 11:09:00 Uhr
Goto Top
Danke Uwe!

Habe es über eine observablecollection gelöst:

 public class ComboBoxOptions
        {
            public string Value { get; set; }
        }

        private ObservableCollection<ComboBoxOptions> _comboObs = new ObservableCollection<ComboBoxOptions>();
        public ObservableCollection<ComboBoxOptions> ComboObs
        {
            get
            {
                return this._comboObs;
            }
            set
            {
                this._comboObs = value;
            }
        }

zum Befüllen und was selected sein soll:

private void Initialize()
        {
            ComboObs.Add(new ComboBoxOptions() { Value = "A" });  
            ComboObs.Add(new ComboBoxOptions() { Value = "B" });  
            ComboObs.Add(new ComboBoxOptions() { Value = "C" });  

            // Was soll selected sein
            ComboObsSelection = ComboObs.FirstOrDefault(x => x.Value == "B").Value;  

            // Selected Value lesen
            var test = ComboObsSelection;
        }

Funktioniert perfekt für mich!

lg, mayho
Mitglied: colinardo
colinardo 06.04.2016 um 12:59:37 Uhr
Goto Top
"Jedem Tierchen sein pläsierchen" wie man so schön sagt face-smile

Grüße Uwe