C# Bind class field to Textbox - c#

I want to bind the property FilePath from the class SExcelFile to a textblox. Here is my file structur.
Inside my MainWindow.xaml is just an textblox.
<TextBox Text="{Binding FilePath}" Grid.ColumnSpan="2" Grid.Row="3" Margin="5" Padding="5"/>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public SManagerRoot ManagerRoot = new SManagerRoot();
public MainWindow()
{
InitializeComponent();
this.DataContext = this.ManagerRoot.ExcelFileManager.ExcelFile;
}
}
SManagerRoot.cs
public class SManagerRoot
{
#region Properties
public SExcelFileManager ExcelFileManager = new SExcelFileManager();
#endregion Properties
}
SExcelFileManager.cs
public class SExcelFileManager
{
#region Properties
public SExcelFile ExcelFile { get; set; }
public SPersonManager PersonManager = new SPersonManager();
#endregion Properties
}
SExcelFile.cs
public class SExcelFile : INotifyPropertyChanged
{
#region Properties
private string _filePath;
public string FilePath
{
set { this._filePath = value; OnPropertyChanged("FilePath"); }
get { return this._filePath; }
}
#endregion Properties
#region c'tor
public SExcelFile()
{
}
public SExcelFile(string filePath)
{
this.FilePath = filePath;
}
#endregion c'tor
#region PropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(name));
}
#endregion PropertyChanged
}
I added a datacontext. The Binding is to the property FilePath and the onpropertychanged is called when the value is changed. Where is the problem?

Related

get Variable from running Task and display on View

The code below executes fine when MyActionFunc is called but not when the function is in another class. MessageBox displays the correct string but it is not shown on view. What I am missing?
class ViewModel : INotifyPropertyChanged
{
public MyCommand ActionCommand
{
get;
set;
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyname = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
public ViewModel()
{
ActionCommand = new MyCommand();
ActionCommand.CanExecuteFunc = obj => true;
// ActionCommand.ExecuteFunc = MyActionFunc;
ActionCommand.ExecuteFunc = MyClass.MyActionFunc;
}
private string myname;
public string myName
{
get => myname;
set { myname = value;; OnPropertyChanged(); }
}
public void MyActionFunc(object parameter)
{
myName = "Fred";
}
}
class MyClass
{
public static void MyActionFunc(object parameter)
{
ViewModel name = new ViewModel();
name.myName = "Fred";
MessageBox.Show(name.myName);
}
}
... and the binding to the Textbox
<TextBox Name="textBox" Grid.Column="1" Grid.Row="1" Text="{Binding Path=myName, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>

How to use BindingContext in Xamarin

I am new to Xamarin but i tried to use BindingContext to set image path
First i tried with
private string _imagePath;
public string ImagePath
{
get
{
return _imagePath;
}
set
{
if (_imagePath != value)
{
_imagePath = value;
OnPropertyChanged();
}
}
}
.
.
.
ImagePath = "TriangleSide_A.png";
.
.
.
<Image Source="{Binding ImagePath}" HeightRequest="300" WidthRequest="300"/>
But no luck then i tried with Auto Property
public string ImagePath {get;set;}
Thats work only with
public string ImagePath {get;} = "TriangleSide_A.png";
According to your description, I don't know how you implement INotifyPropertyChanged interface, generally, I do like this:
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
The RaisePropertyChanged likes your OnPropertyChanged method, with the PropertyName that has changed. If we go to our property, we now need to update it, to raise this event, every time the property is changed.
From your code, you don't add propertyname in your OnPropertyChanged, so the ImagePath can not be updated.
Please take a look the following code:
<StackLayout>
<Image
HeightRequest="300"
Source="{Binding ImagePath}"
WidthRequest="300" />
<Button
x:Name="btn1"
Clicked="Btn1_Clicked"
Text="change image source" />
</StackLayout>
public partial class Page32 : ContentPage, INotifyPropertyChanged
{
private string _imagePath;
public string ImagePath
{
get { return _imagePath; }
set
{
if (_imagePath != value)
{
_imagePath = value;
RaisePropertyChanged("ImagePath");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public Page32()
{
InitializeComponent();
ImagePath = "a11.jpg";
this.BindingContext = this;
}
private void Btn1_Clicked(object sender, EventArgs e)
{
ImagePath = "a12.jpg";
}
}
Update:
If you want to use binding in mvvm mode, I do some code that you can take a look:
This is ImageOnClick model, contain some properties.
public class ImageOnClick:ViewModelBase
{
private string _imagePath;
public string ImagePath
{
get { return _imagePath; }
set
{
if (_imagePath != value)
{
_imagePath = value;
RaisePropertyChanged("ImagePath");
}
}
}
}
Now binding this model to contentpage
public partial class Page32 : ContentPage
{
private ImageOnClick imagemodel;
public Page32()
{
InitializeComponent();
imagemodel = new ImageOnClick() { ImagePath = "a11.jpg" };
this.BindingContext = imagemodel;
}
private void Btn1_Clicked(object sender, EventArgs e)
{
imagemodel.ImagePath = "a12.jpg";
}
}
About mvvm binding, you can also take a look:
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/xaml/xaml-basics/data-bindings-to-mvvm
Your Initial code is correct, but you can set the _imagePath to Auto Property like so:
private string _imagePath { get; set; }
public string ImagePath
{
get
{
return _imagePath;
}
set
{
if (_imagePath != value)
{
_imagePath = value;
OnPropertyChanged();
}
}
}
The reason
public string ImagePath {get;set;}
doesn't work is because you need to have the OnPropertyChanged() in the setter.

WPF MVVM Switching Between Usercontrols

I am new to MVVM. I found this artcle and it resolve my haf of problems.
https://social.technet.microsoft.com/wiki/contents/articles/30898.simple-navigation-technique-in-wpf-using-mvvm.aspx
However, I need to navigate from one usercontrol to another from the button click event of one usercontrol not from the button on the main window.
Usercontrol 1:
Usercontrol 2:
This is what I have tried sofar;
class Usercontrol1ViewModel : INotifyPropertyChanged
{
public ICommand navCommand { get; set; }
public Usercontrol1ViewModel()
{
navCommand = new BaseCommand(navigate);
}
private void navigate(object obj)
{
NavigationViewModel mainViewModel = new NavigationViewModel();
mainViewModel.SelectedViewModel = new Usercontrol2ViewModel();
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
NavigationView model class
Class NavigationViewModel : INotifyPropertyChanged
{
public ICommand btn1Command { get; set; }
public ICommand btn2Command { get; set; }
private object selectedViewModel;
public object SelectedViewModel
{
get { return selectedViewModel; }
set { selectedViewModel = value; OnPropertyChanged("SelectedViewModel"); }
}
public NavigationViewModel()
{
btn1Command = new BaseCommand(Opencontrl1);
btn2Command = new BaseCommand(Opencontrl2);
}
private void Opencontrl1(object obj)
{
SelectedViewModel = new Usercontrol1ViewModel();
}
private void Opencontrl2(object obj)
{
SelectedViewModel = new Usercontrol2ViewModel();
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
Main window code behind;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new NavigationViewModel();
}
}
Can somebody guide me how to achieve this with MVVM?
Try the below code. I used the sample code in the article and I am the author of the MSDN article :)
MainWindow.xaml
<Window.Resources>
<DataTemplate DataType="{x:Type local:EmployeeViewModel}">
<local:EmployeeView/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:DepartmentViewModel}">
<local:DepartmentView/>
</DataTemplate>
</Window.Resources>
<DockPanel LastChildFill="True">
<ContentControl x:Name="Pages" DockPanel.Dock="Right" Content="{Binding SelectedViewModel}"/>
</DockPanel>
NavigationViewModel
class NavigationViewModel : INotifyPropertyChanged
{
public EmployeeViewModel EmployeeViewModel { get; set; }
public DepartmentViewModel DepartmentViewModel { get; set; }
private object selectedViewModel;
public object SelectedViewModel
{
get { return selectedViewModel; }
set { selectedViewModel = value; OnPropertyChanged("SelectedViewModel"); }
}
public NavigationViewModel()
{
SelectedViewModel = new EmployeeViewModel(OpenEmp);
}
private void OpenEmp(object obj)
{
if (obj.ToString() == "Dept")
{
SelectedViewModel = new DepartmentViewModel();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
EmployeeView
<Grid>
<StackPanel>
<TextBlock Text="This is employee view"/>
<Button Content="Navigate to Dept View" Command="{Binding Navigate}"/>
</StackPanel>
</Grid>
EmployeeViewModel
class EmployeeViewModel
{
private readonly Action<object> navigate;
public ICommand Navigate { get; set; }
public EmployeeViewModel(Action<object> navigate)
{
Navigate = new BaseCommand(OnNavigate);
this.navigate = navigate;
}
private void OnNavigate(object obj)
{
navigate.Invoke("Dept");
}
}

c# ListView not updating when Property Changed

My UI is not updating when more data is added to the ObservableCollection. The console output says A first chance exception of type 'System.NullReferenceException' occurred. Should I be using Inotifycollectionchanged instead? Here is some of the code:
<ListView x:Name="ListView2" ItemsSource="{Binding Source={x:Static d:GrabUserConversationModel._Conversation}, UpdateSourceTrigger=PropertyChanged}" SelectionChanged="ListView1_SelectionChanged">
UserConversationModel.cs
public class UserConversationModel : INotifyPropertyChanged
{
public UserConversationModel()
{
}
public string Name
{ get; set; }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string Obj)
{
if (PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(Obj));
}
}
}
MainWindow.xaml.cs
public partial class MainWindow
{
static GrabUserConversationModel grabUserConversationModel;
public MainWindow()
{
InitializeComponent();
...
}
static void AddData()
{
grabUserConversationModel.Conversation.Add(new UserConversationModel { Name = "TestName" });
}
GrabUserConversationModel.cs
class GrabUserConversationModel
{
public static ObservableCollection<UserConversationModel> _Conversation = new ObservableCollection<UserConversationModel>();
public ObservableCollection<UserConversationModel> Conversation
{
get { return _Conversation; }
set { _Conversation = value; }
}
...
your property ObservableCollection<UserConversationModel> Conversation is not implementing the INotifyPropertyChanged
public ObservableCollection<UserConversationModel> Conversation
{
get { return _Conversation; }
set { _Conversation = value; OnPropertyChanged("Conversation");}
}

WPF DataGrid-DataGridCheckBoxColumn vs2010 c# .net

I am working in vs2010.
I have created a DataGrid which is bounded to
ObservableCollection List;
the Class_CMD looks like this :
public class Class_RetrieveCommand
{
public string CMD { get; set; }
public bool C_R_CMD { get; set; }
public bool S_CMD { get; set; }
public bool C_S_CMD { get; set; }
}
i have 4 delegates which i pass to another window, and this window needs to update the list during runtime. During the runtime i can see the string column of the grid updated all the time but the DataGridCheckBoxColumns are never updated.
the DataGrid -
<DataGrid Background="Transparent" x:Name="DataGrid_CMD" Width="450" MaxHeight="450" Height="Auto" ItemsSource="{Binding}" AutoGenerateColumns="True">
one of the delegates which updates the bool is -
public void UpdateC_S_CMD(string Msg)
{
foreach (Class_CMD c in List.ToArray())
{
if (c.CMD.Equals(Msg))
c.C_S_CMD = true;
}
}
I don't understand why the bool columns are not updated....
can anyone help please?
thanks.
Your class Class_RetrieveCommand needs to implement the INotifyPropertyChanged interface. Otherwise the individual rows databound to the instances of the class don't know that the underlying properties have changed. If you change it to something like this, you should see the changes reflected in your grid:
public class Class_RetrieveCommand : INotifyPropertyChanged
{
private bool _cRCmd;
private bool _cSCmd;
private string _cmd;
private bool _sCmd;
public string CMD
{
get { return _cmd; }
set
{
_cmd = value;
InvokePropertyChanged(new PropertyChangedEventArgs("CMD"));
}
}
public bool C_R_CMD
{
get { return _cRCmd; }
set
{
_cRCmd = value;
InvokePropertyChanged(new PropertyChangedEventArgs("C_R_CMD"));
}
}
public bool S_CMD
{
get { return _sCmd; }
set
{
_sCmd = value;
InvokePropertyChanged(new PropertyChangedEventArgs("S_CMD"));
}
}
public bool C_S_CMD
{
get { return _cSCmd; }
set
{
_cSCmd = value;
InvokePropertyChanged(new PropertyChangedEventArgs("C_S_CMD"));
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
public void InvokePropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, e);
}
}
}
You should implement INotifyPropertyChanged in the Class_RetrieveCommand like this:
public class Class_RetrieveCommand : INotifyPropertyChanged
{
private string _CMD;
public string CMD
{
get { return _CMD; }
set { _CMD = value; OnPropertyChanged("CMD"); }
}
... similar for the other properties
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Unfortunately you can't use auto properties anymore then (except you resort to proxygenerators).

Categories