I want to write a lottery number generator program by using wpf and MVVM structure. I wrote the code below but nothing work. Can you everyone help me?
I have found no mistake and build and debug!
class MainViewModel : ViewModelBase
{
private int duration;
private string text;
private DispatcherTimer timer = null;
public MainViewModel()
{
this.Duration = 1000;
this.Text = "00";
this.StartTimerCommand = new Delegatecommon(this.StartTimer);
this.StopTimerCommand = new Delegatecommon(this.StopTimer);
}
#region Properties
public int Duration
{
get
{
return this.duration;
}
set
{
this.duration = value;
RaisePropertychange("Duration");
}
}
public string Text
{
get
{
return this.text;
}
set
{
this.text = value;
RaisePropertychange("Text");
}
}
public Delegatecommon StartTimerCommand
{
get;
set;
}
public Delegatecommon StopTimerCommand
{
get;
set;
}
#endregion
public void StartTimer()
{
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(this.Duration);
timer.Tick += new EventHandler(TimerTick);
timer.Start();
}
public void StopTimer()
{
if (timer != null)
{
timer.Stop();
timer = null;
}
}
private void TimerTick(object send, EventArgs e)
{
Random rnd = new Random((Int32)DateTime.Now.Ticks);
this.Text = rnd.Next(0, 100).ToString();
}
}
In your MainViewModel() add this line: Edited
public MainViewModel()
{
this.Duration = 1000;
this.Text = "00";
timer = new DispatcherTimer();
timer.Interval = this.Duration;
timer.Tick += new EventHandler(TimerTick);
this.StartTimerCommand = new Delegatecommon(this.StartTimer);
this.StopTimerCommand = new Delegatecommon(this.StopTimer);
}
public void StartTimer()
{
timer.Start();
}
public void StopTimer()
{
timer.Stop();
}
Keeping the rest same as before.
After 30 minutes of scrutiny, I figured out 2 words you're missing...
&& PropertyChanged != null in:
class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertychange(string propertyname)
{
if (propertyname != null && PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
}
}
}
Adding that, it worked when I test your code, with my extra modifications that I asked you to make here.
class Delegatecommon : ICommand
{
private Action _execute;
private Func<bool> _canexecute;
public Delegatecommon(Action ac) : this(ac, () => true) { }
public Delegatecommon(Action ac, Func<bool> fu)
{
if (ac == null)
throw new ArgumentNullException();
else if (fu == null)
throw new ArgumentNullException();
_execute = ac;
_canexecute = fu;
}
event EventHandler ICommand.CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
}
remove
{
CommandManager.RequerySuggested -= value;
}
}
public void execute()
{
_execute();
}
public bool canexecute()
{
return _canexecute();
}
bool ICommand.CanExecute(object parameter)
{
return canexecute();
}
void ICommand.Execute(object parameter)
{
execute();
}
}
<Window x:Class="Randm.View.MainView"
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:Randm.ViewModel"
mc:Ignorable="d"
Title="RandomNumber" Height="300" Width="300">
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock FontSize="50" VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding Path=Text,UpdateSourceTrigger=PropertyChanged}"></TextBlock>
<StackPanel Grid.Row="1">
<Button Width="100" Height="50" Content="Start" FontSize="20" Command="{Binding Path=StartTimerCommand}"></Button>
<Button Width="100" Height="50" Content="Stop" FontSize="20" Command="{Binding Path=StopTimerCommand}"></Button>
</StackPanel>
</Grid>
class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertychange(string propertyname)
{
if(propertyname == null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
}
}
}
Related
I'm trying to bind a textbox (named Labour) and textblock (which shows time) with listview. Listview should show a names of labours and times that they're takes after cliking button "Add item". I've already tried to use observablecollection but I'm doing something wrong. Data in ListView should be separated in two columns.
How can i do that ?
XAML:
<Window x:Class="LabourTimer.View.LabourMainWindow"
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:LabourTimer.View"
mc:Ignorable="d"
xmlns:viewmodel="clr-namespace:LabourTimer.ViewModel"
Title="Labour timer" Height="600" Width="515">
<Window.Resources>
<viewmodel:LabourViewModel x:Key="viewModel"/>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel>
<Label Content="Timer:" Grid.Row="0"/>
<TextBlock Text="{Binding CurrentTime}" Grid.Row="0"/>
<Label Content="Labour name:"/>
<TextBox x:Name="Labour" Text="{Binding labourName, Mode=TwoWay}"/>
</StackPanel>
<StackPanel Grid.Column="1">
<Button Content="Start/Stop" Command="{Binding StartStopCommand}"/>
<Button Content="Reset" Command="{Binding ResetCommand}"/>
<Button Content="Add to list" Command="{Binding AddCommand}"/>
<Button Content="Remove from list"/>
</StackPanel>
<ListView x:Name="listView" Height="Auto" Margin="0,5" Grid.Row="1" VerticalAlignment="Top" Grid.ColumnSpan="2" MinWidth="300">
<ListView.View>
<GridView>
<GridViewColumn Header="Labour name" Width="400" />
<GridViewColumn Header="Time in seconds" Width="100"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
ViewModel:
namespace LabourTimer.ViewModel
{
public class LabourViewModel : INotifyPropertyChanged
{
private DispatcherTimer _timer;
private string _currentTime;
private int _seconds;
private bool _running;
public ICommand StartStopCommand { get; set; }
public ICommand ResetCommand { get; set; }
public ICommand AddCommand { get; set; }
public string CurrentTime
{
get { return _currentTime; }
set { _currentTime = value;
OnPropetyChanged("CurrentTime");
}
}
public LabourViewModel()
{
_timer = new DispatcherTimer();
_timer.Interval = TimeSpan.FromSeconds(1);
_timer.Tick += new EventHandler(TimerTick);
_running = false;
CurrentTime = "0";
LoadCommands();
}
private void LoadCommands()
{
StartStopCommand = new CustomCommand(StartStopTimer, CanStartStopTimer);
ResetCommand = new CustomCommand(ResetTimer, CanResetTimer);
AddCommand = new CustomCommand(AddLabour, CanAddLabour);
}
private void AddLabour(object obj)
{
}
private bool CanAddLabour(object obj)
{
return true;
}
private bool CanResetTimer(object obj)
{
if (CurrentTime != "0")
return true;
else
return false;
}
private void ResetTimer(object obj)
{
_timer.Stop();
CurrentTime = "0";
_seconds = 0;
}
private void StartStopTimer(object obj)
{
if (_running == false)
{
_timer.Start();
_running = true;
}
else
{
_timer.Stop();
_running = false;
}
}
private bool CanStartStopTimer(object obj)
{
return true;
}
private void TimerTick(object send, EventArgs e)
{
_seconds++;
CurrentTime = _seconds.ToString();
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropetyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
CustomCommand:
public class CustomCommand : ICommand
{
private Action<object> execute;
private Predicate<object> canExecute;
public CustomCommand(Action<object> execute, Predicate<object> canExecute)
{
this.execute = execute;
this.canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
}
remove
{
CommandManager.RequerySuggested -= value;
}
}
public bool CanExecute(object parameter)
{
bool b = canExecute == null ? true : canExecute(parameter);
return b;
}
public void Execute(object parameter)
{
execute(parameter);
}
}
}
MainWindow:
public partial class LabourMainWindow : Window
{
public LabourMainWindow()
{
InitializeComponent();
DataContext = new LabourViewModel();
}
So I have the following XAML:
<TextBlock Text="{Binding DisconnectedDevices, UpdateSourceTrigger=PropertyChanged}" />
The view model has the following properties:
public string DisconnectedDevices {get; set;}
public IEnumerable<IDeviceInformationVM> DeviceCollection {get; set;}
There's a method that gets called which raises the property notified event:
public void DeviceCollectionChanged()
{
RaisePropertyChanged(() => DeviceCollection);
}
I'd like to update the value in the TextBlock when DeviceCollection changes. I'm aware that I could just call RaisePropertyChanged on DisconnectedDevices but I'm wondering if its possible to update a TextBlock on a different property change event.
Thanks all!
EDIT: Thanks for the suggestions for using an ObservableCollection instead of IEnumerable, unfortunately, I'm not at liberty to change the collection type..
The DeviceCollectionChanged method is called whenever the collection changes (tedious I know...)
FURTHER EDIT:
Have just gone ahead with
RaisePropertyChanged(() => DisconnectedDevices);
I appreciate not enough information might have been provided in the question to get what I was trying to do, apologies for that
I am not sure if your current code works, but assuming it works.
Why not use - ObservableCollection<IDeviceInformationVM> instead of IEnumerable<IDeviceInformationVM> DeviceCollection you wont need the DeviceCollectionChanged event. It will be taken care.
Yes you can raise
public void DeviceCollectionChanged()
{
RaisePropertyChanged(() => DeviceCollection);
RaisePropertyChanged(() => DisconnectedDevices);
// or RaisePropertyChanged("DisconnectedDevices"); Whichever works
}
See this question, it might help you with implementation of NotifyPropertyChanged for multiple properties- WPF Notify PropertyChanged for a Get Property
Do you call the DeviceCollectionChanged() method everytime you change your DeviceCollection? How do you set DeviceCollection?
You can implement an ObservableCollection (bottom of this answer), or, depending on how you set your DeviceCollection, if for example DeviceCollection comes from a list, you can implement something like this:
private IEnumerable<IDeviceInformationVM> deviceCollection;
public IEnumerable<IDeviceInformationVM> DeviceCollection
{
get
{
return deviceCollection;
}
set
{
deviceCollection = value;
RaisePropertyChanged(() => DisconnectedDevices);
RaisePropertyChanged(() => DeviceCollection);
}
}
DeviceCollection = GetListOfIDeviceInformationVM(); //will automatically raise property changed and update your TextBlock
You won't have to keep on calling RaisePropertyChanged() which looks rather tedious
Change the type of the CollectionDevice collection to ObservableCollection then, raise the event CollectionChanged as follows :
DeviceCollection.CollectionChanged + = DeviceCollection_CollectionChanged;
I give you an implemention in MVVM with a class RelayCommand
here the view : (MainView)
<Window x:Class="WpfApplication.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:WpfApplication"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding DisconnectedDevices, Mode=TwoWay}" Height="25" Width="175" Grid.Row="0" />
<Button Grid.Row="1" Content="Click" Command="{Binding ToggleExecuteCommand}" Width="100" Height="25"/>
</Grid>
the ViewModel (Main ViewModel)
using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
namespace WpfApplication
{
public class MainViewModel : INotifyPropertyChanged
{
private string disconnectedDevices;
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
public MainViewModel()
{
ToggleExecuteCommand = new RelayCommand(ChangeCollection);
DeviceCollection = new ObservableCollection<DeviceInformationVM>();
DeviceCollection.CollectionChanged += DeviceCollection_CollectionChanged;
}
private void ChangeCollection(object obj)
{
DeviceCollection.Add(new DeviceInformationVM { MyProperty = "TEST" });
}
private void DeviceCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
NotifyCollectionChangedAction action = e.Action;
if (action == NotifyCollectionChangedAction.Add)
{
DisconnectedDevices = "Somme thing added to collection";
}
if (action == NotifyCollectionChangedAction.Remove)
{
DisconnectedDevices = "Somme thing removed from collection";
}
}
public string DisconnectedDevices
{
get { return this.disconnectedDevices; }
set
{
if (value != this.disconnectedDevices)
{
this.disconnectedDevices = value;
NotifyPropertyChanged("DisconnectedDevices");
}
}
}
public ObservableCollection<DeviceInformationVM> DeviceCollection { get; set; }
public RelayCommand ToggleExecuteCommand { get; set; }
}
}
the RelayCommand :
using System;
using System.Windows.Input;
namespace WpfApplication
{
public class RelayCommand : ICommand
{
private Action execute;
private Predicate<object> canExecute;
private event EventHandler CanExecuteChangedInternal;
public RelayCommand(Action<object> execute)
: this(execute, DefaultCanExecute)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
}
if (canExecute == null)
{
throw new ArgumentNullException("canExecute");
}
this.execute = execute;
this.canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
this.CanExecuteChangedInternal += value;
}
remove
{
CommandManager.RequerySuggested -= value;
this.CanExecuteChangedInternal -= value;
}
}
public bool CanExecute(object parameter)
{
return this.canExecute != null && this.canExecute(parameter);
}
public void Execute(object parameter)
{
this.execute(parameter);
}
public void OnCanExecuteChanged()
{
EventHandler handler = this.CanExecuteChangedInternal;
if (handler != null)
{
handler.Invoke(this, EventArgs.Empty);
}
}
public void Destroy()
{
this.canExecute = _ => false;
this.execute = _ => { return; };
}
private static bool DefaultCanExecute(object parameter)
{
return true;
}
}
}
and finaly DeviceInformation
using System;
namespace WpfApplication
{
public interface IDeviceInformationVM
{
string MyProperty { get; set; }
}
public class DeviceInformationVM : IDeviceInformationVM
{
public string MyProperty
{
get; set;
}
}
}
Hope it helps
I noticed that it happends not only in the one project but on multiple too so I will provide simple example. I've got such xaml:
<Page
x:Class="TestApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Button Content="Button" Command="{Binding PressedButton}" HorizontalAlignment="Left" Margin="0,-10,0,-9" VerticalAlignment="Top" Height="659" Width="400"/>
</Grid>
</Page>
my classes to binding data:
public abstract class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
var e = new PropertyChangedEventArgs(propertyName);
this.PropertyChanged(this, e);
}
}
}
public class Command : ICommand
{
private Action<object> action;
public Command(Action<object> action)
{
this.action = action;
}
public bool CanExecute(object parameter)
{
if (action != null)
{
return true;
}
else
{
return false;
}
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
if (action != null)
{
action((string)parameter);
}
}
}
public class TestViewModel : ObservableObject
{
public ICommand PressedButton
{
get
{
return new Command((param) => { });
}
}
}
and main page:
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
DataContext = new TestViewModel();
}
It's weird but PressedButton runs only on application start(isn't that weird it runs on start?). After that, even after button click there is nothing triggered. I can't figure out what's wrong.
I think you may be causing binding issues by returning a new command each time the "getter" is called. Try setting the command once, in your constructor (for example).
public MainPage()
{
PressedAdd = new Command(param => SaveNote());
}
public ICommand PressedAdd { get; private set; }
In the SaveNote() method, you could test the values and either save (or not save) them:
private void SaveNote()
{
if (NoteTitle == null || NoteContent == null)
return;
// Do something with NoteTitle and NoteContent
}
UPDATE 1 : You can download the sample project from here.
Can you please help me to find the error in my code. I can't able to assign item source to combo box as well as button click event in WinRT app. I am using MVVM and MetroEventToCommand. I am new to MVVM concept, so please answer my silly question.
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Button Content="Click Here">
<mvvm:EventToCommandManager.Collection>
<mvvm:EventToCommand Command="{Binding ButtonClickCommand}" Event="Click"/>
</mvvm:EventToCommandManager.Collection>
</Button>
<ComboBox x:Name="FontsCombo" Height="50" Width="150" SelectedItem="{Binding SelectedFont}" ItemsSource="{Binding fonts}" />
<TextBlock FontSize="30" Text="{Binding SelectedFont}"/>
</Grid>
public MainPage()
{
this.InitializeComponent();
this.DataContext = new VM();
}
public class VM : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public RelayCommand ButtonClickCommand { get; set; }
private ObservableCollection<string> _fonts = new ObservableCollection<string>();
public ObservableCollection<string> fonts
{
get { return _fonts; }
set
{
_fonts = value;
if (null != PropertyChanged)
{
PropertyChanged(this, new PropertyChangedEventArgs("fonts"));
}
}
}
private string _SelectedFont = "";
public string SelectedFont
{
get { return _SelectedFont; }
set
{
// Some logic here
_SelectedFont = value;
if (null != PropertyChanged)
{
PropertyChanged(this, new PropertyChangedEventArgs("SelectedFont"));
}
}
}
public VM()
{
fonts.Add("Arial");
fonts.Add("Courier New");
fonts.Add("Times New Roman");
ButtonClickCommand = new RelayCommand(Click);
}
private void Click()
{
new Action(async () => await new Windows.UI.Popups.MessageDialog("Testing dialog").ShowAsync()).Invoke();
}
}
For the SelectedItem, you didn't specify the Mode=TwoWay :
<ComboBox x:Name="FontsCombo" Height="50" Width="150" SelectedItem="{Binding SelectedFont, Mode=TwoWay}" ItemsSource="{Binding fonts}" />
EDIT
I found the solution :
public class VM : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public RelayCommand ButtonClickCommand { get; set; }
private ObservableCollection<string> _fonts;
public ObservableCollection<string> fonts
{
get { return _fonts; }
set
{
_fonts = value;
if (null != PropertyChanged)
{
PropertyChanged(this, new PropertyChangedEventArgs("fonts"));
}
}
}
private string _SelectedFont;
public string SelectedFont
{
get { return _SelectedFont; }
set
{
// Some logic here
_SelectedFont = value;
if (null != PropertyChanged)
{
PropertyChanged(this, new PropertyChangedEventArgs("SelectedFont"));
}
}
}
public VM()
{
this.fonts = new ObservableCollection<string>();
fonts.Add("Arial");
fonts.Add("Courier New");
fonts.Add("Times New Roman");
ButtonClickCommand = new RelayCommand(Click);
}
private void Click()
{
new Action(async () => await new Windows.UI.Popups.MessageDialog("Testing dialog").ShowAsync()).Invoke();
}
}
If I instance fonts in the constructor, the UX is not freezing anymore.
I am using INotifyPropertyChanged but it will give me null when I shaw the PropertyChanged so what i can do..
my code is like this..
public class Entities : INotifyPropertyChanged
{
public Entities(int iCount)
{
_iCounter = iCount;
}
private int _iCounter;
public int iCounter
{
get
{
return _iCounter;
}
set
{
value = _iCounter;
NotifyPropertyChanged("iCounter");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
Thanks...
I tried putting your code in my program and it is working fine. I am getting the EventArg as the property:
class Program
{
static void Main(string[] args)
{
var ent = new Entities(10);
ent.PropertyChanged += new PropertyChangedEventHandler(ent_PropertyChanged);
ent.iCounter = 100;
}
static void ent_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
throw new NotImplementedException();
}
}
public class Entities : INotifyPropertyChanged
{
public Entities(int iCount)
{
_iCounter = iCount;
}
private int _iCounter;
public int iCounter
{
get
{
return _iCounter;
}
set
{
_iCounter = value;
NotifyPropertyChanged("iCounter");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
What is the exact erro you are getting?
This is i think a bug in INotifyPropertyChanged .
There can be 2 workaround
1st Workaround
1- Assign iCounter property to a UI control like Lable.
2- Now change the value of the property this time , PropertyChanged event will have a reference of your method and will not be null;
2nd workaround
Assign PropertyChanged delegate in the Entities class constructor
i am giving the demo code in WPF
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.Resources>
<ToolTip x:Key="#tooltip">
<TextBlock Text="{Binding CompanyName}"/>
</ToolTip>
</Grid.Resources>
<TextBlock Text="{Binding Name}" Background="LightCoral" />
<Rectangle Width="200" Height="200" Fill="LightBlue" VerticalAlignment="Center" HorizontalAlignment="Center" ToolTip="{DynamicResource #tooltip}" Grid.Row="1"/>
<Button Click="Button_Click" Grid.Row="2" Margin="20">Click Me</Button>
</Grid>
see here CompanyName is assigned to a tool tip.
// this is Window1.Cs file
public Window1()
{
DataContext = DemoCustomer.CreateNewCustomer();
InitializeComponent();
}
// Now DemoCustomer Class
public class DemoCustomer : INotifyPropertyChanged
{
// These fields hold the values for the public properties.
private Guid idValue = Guid.NewGuid();
private string customerName = String.Empty;
private string companyNameValue = String.Empty;
private string phoneNumberValue = String.Empty;
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
// The constructor is private to enforce the factory pattern.
private DemoCustomer()
{
customerName = "no data";
companyNameValue = "no data";
phoneNumberValue = "no data";
}
// This is the public factory method.
public static DemoCustomer CreateNewCustomer()
{
return new DemoCustomer();
}
// This property represents an ID, suitable
// for use as a primary key in a database.
public Guid ID
{
get
{
return this.idValue;
}
}
public string CompanyName
{
get { return this.companyNameValue; }
set
{
if (value != this.companyNameValue)
{
this.companyNameValue = value;
OnPropertyChanged("CompanyName");
}
}
}
public string PhoneNumber
{
get { return this.phoneNumberValue; }
set
{
if (value != this.phoneNumberValue)
{
this.phoneNumberValue = value;
OnPropertyChanged("PhoneNumber");
}
}
}
}
and finally changing the value
private void Button_Click(object sender, RoutedEventArgs e)
{
DemoCustomer dc = this.DataContext as DemoCustomer;
dc.CompanyName = "Temp";
}