简体   繁体   中英

c# wpf data binding not happening.

I am a bit new on c# WPF. I have been following MVVM pattern and everything is set, my code seem to work fine but Issue I am facing is when I bind the data on xaml file, the data I am receiving from get set property but binding seems to have gone as no data is displayed on my text box. check my code.

/**********************xaml code***********************************\\

<UserControl x:Class="ILS.debugger.debuggermsg"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:serial="clr-namespace:ILS.VM.Serial_Monitor;assembly=ILS.VM"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <TextBox Text="{Binding Debugger_Recoreded}" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Background="#FFEBD3D3">

        </TextBox>  
    </Grid>
</UserControl>

/***********************viewmodel code******************\\

namespace ILS.VM.Serial_Monitor
{
   public class serial : NotifyPropertyChanged
    {
        private string debuger_rec;
        public string Debugger_Recoreded
        {
            get { return debuger_rec; }
            set
            {

                if (this.debuger_rec == value)
                    return;

                this.debuger_rec = value;
                i--;
                if (i == 0)
                {
                    this.debuger_rec = String.Empty;

                    i = 1000;
                }
                this.InvokePropertyChanged("Debugger_Recoreded");   

           }    

        }

/***********************model******************\\ namespace ILS

 public void OnDebugger(String Receved_Data) //debug message monitor code
        {
            try
            {

                this.serialData.Debugger_Recoreded += "  " + DateTime.Now + "  " + Receved_Data + Environment.NewLine;
                this.serialData.Debugger_Recoreded += Environment.NewLine;
            }
            catch (Exception e)
            {
            }
        }
public class serial : INotifyPropertyChanged
    {
        private string debuger_rec;
        public string Debugger_Recoreded
        {
            get { return debuger_rec; }
            set
            {

                if (this.debuger_rec == value)
                    return;

                this.debuger_rec = value;
                i--;
                if (i == 0)
                {
                    this.debuger_rec = String.Empty;

                    i = 1000;
                }
                OnPropertyChanged("Debugger_Recoreded");   

           }    


    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string name)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                {
                    handler(this, new PropertyChangedEventArgs(name));
                }
        }
        }

And set DataContext too, in main windows enter this lines:

this.DataContext = serialData;

Also you can use mode way to bind.

 <TextBox Text="{Binding Debugger_Recoreded,Mode="Towway"}" />

In your code-behind (ie your debuggermsg class), you have to instantiate and assign a DataContext:

public debuggermsg()
{
    InitializeComponent();
    this.DataContext = new serial();
}

It is required for DataBinding, so that you will be able to interact with your ViewModel's properties.

Then, modify your ViewModel like so:

public class serial : INotifyPropertyChanged
{
    private string debuger_rec;
    public string Debugger_Recoreded
    {
        get { return debuger_rec; }
        set
        {
            if (this.debuger_rec == value)
                return;

            this.debuger_rec = value;
            i--;
            if (i == 0)
            {
                this.debuger_rec = String.Empty;

                i = 1000;
            }
            OnPropertyChanged("Debugger_Recoreded");   
        }    
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

Implementation of OnPropertyChanged method is required to notify your view of a modification of your ViewModel's property.

Everything should be fine then.

When implementing INotifyPropertyChanged it's best to use [CallerMemberName] attribute, it's in the System.Runtime.CompilerServices , as you don't have to hardcode a string name of the calling property:

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName]string propertyName = "")
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }         

Now you can write your property like this:

private string debuggerRecorded;
public string DebuggerRecorded
{
    get
    { 
        return debuggerRecorded; 
    }
    set
    {   
        if (debuggerRecorded != value)  
        {
            this.debuggerRecorded = value;
            i--;
            if (i == 0)
            {
                 this.debuggerRecorded = String.Empty;
                 i = 1000;
            }
            OnPropertyChanged(); // No argument needed   
        }    
    }
}  

By doing this you don't have to worry about spelling and you can freely change the names of your properties in the future, you don't have to remember to change it also in the OnPropertyChanged .

Assuming everything else works fine with your code you just need to set DataContext, which is usually done in MainWindow. For example, like this:

public partial class MainWindow : Window
    {
        private Serial viewModel;
        public MainWindow()
        {
            InitializeComponent();
            viewModel = new Serial();
            this.DataContext = viewModel;
        }
    }  

Also, you may want to write your text box with another property:

TextBox Text="{Binding DebuggerRecorded, UpdateSourceTrigger=PropertyChanged}" ...

If you omit this last part, the Text will get updated only when the TextBox loses focus.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM