I have text block on my UI. I would like to display some text on the text block dynamically. I have implemented it as given in the below code. however i do not see the values updating dynamically. I do see only the last updated value on UI text block. I have included a delay to notice the change.
Please provide any solution or comment for more info.Thank you in advance.
Code:
namespace TxtBlock
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
SomeObjectClass obj = new SomeObjectClass();
public MainWindow()
{
InitializeComponent();
txtName.DataContext = obj;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
obj.Name = "Hello World";
Thread.Sleep(2000);
obj.Name = "Third";
}
}
class SomeObjectClass : INotifyPropertyChanged
{
private string _name = "hello";
public string Name
{
get
{
return _name;
}
set
{
_name = value;
OnPropertyChanged("Name");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string PropertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
}
}
}
XAML: <Window x:Class="TxtBlock.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Content="Button" HorizontalAlignment="Left" Margin="237,170,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
<TextBlock HorizontalAlignment="Left" Margin="237,256,0,0" TextWrapping="Wrap" x:Name="txtName" Text="{Binding Name}" VerticalAlignment="Top"/>
</Grid>
</Window>
You need to Run in Background thread to update your values in UI TextBlock
Code:
public partial class TextBlockExample : Window
{
ThreadExampleViewModel viewModel = new ThreadExampleViewModel();
public TextBlockExample()
{
InitializeComponent();
this.DataContext = viewModel;
}
private void btnClick_Click(object sender, RoutedEventArgs e)
{
/// Background thread Thread to run your logic
Thread thread = new Thread(YourLogicToUpdateTextBlock);
thread.IsBackground = true;
thread.Start();
}
private void YourLogicToUpdateTextBlock()
{
/// Example i am updating with i value.
for (int i = 0; i < 1000; i++)
{
viewModel.Name = i + " Conut";
Thread.Sleep(1000);
}
}
}
<Grid>
<StackPanel>
<TextBlock x:Name="txtName" Text="{Binding Name}" Height="30" Width="100" Margin="10"/>
<Button x:Name="btnClick" Content="Click" Height="30" Width="100" Margin="10" Click="btnClick_Click"/>
</StackPanel>
</Grid>
public class ThreadExampleViewModel : INotifyPropertyChanged
{
private string name = "Hello";
public string Name
{
get { return name; }
set { name = value; OnPropertyChanged("Name"); }
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string PropertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
}
}
Related
I have two text box and want to copy first textbox value to another textbox whenever I click on Button and this should done by using Commands in WPF.
This is my scenario :
First textbox binds the value from Person class.
Button shows simple MsgBox which verifies that Command executed properly.
Well here, I want to pass first textbox value to 2nd textbox (using Command) ?
XML File:
<Window x:Class="PrismDemo.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:PrismDemo.ViewModels"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<vm:Person x:Name="vmmmm1" />
</Window.DataContext>
<Grid>
<TextBox x:Name="fName" Grid.Row="1" Height="30" Width="100" Text="{Binding Path=FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Button Name="Submit" Grid.Row="2" Height="30" Width="100" Content="Submit Me" Command="{Binding submitCommand}" CommandParameter="{Binding Text, ElementName=fName}"/>
<TextBox x:Name="display" Grid.Row="3" Height="30" Width="100" Text="{}" />
Person class (ViewModel):
public class Person:INotifyPropertyChanged
{
private string _firstName;
private string _copyName;
public ICommand submitCommand {get;set;}
public Person()
{
_firstName = "Ronaldo";
submitCommand = new RelayCommand(MyMethod, canExecuteMethod);
}
public string FirstName
{
get
{
return _firstName;
}
set
{
_firstName = value;
OnPropertyUpdated(FirstName);
//OnPropertyUpdated(CopyName);
}
}
public string CopyName
{
get
{
return _copyName;
}
set
{
OnPropertyUpdated(CopyName);
}
}
private void OnPropertyUpdated(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
private bool canExecuteMethod(object parameter)
{
return true;
}
private void MyMethod(object parameter)
{
MessageBox.Show("Welcome to Command Demo...");
//if (parameter == null) return;
//_copyName = parameter.ToString();
this._copyName = _firstName;
}
public event PropertyChangedEventHandler PropertyChanged;
}
Any help will be appreciated.
Thank you !!
You were almost right ....Its working at my place properly , Just make following changes in you code
Just remove command parameter... we dont need it and Bind the copied string.
<TextBox Grid.Row="1" Height="30" Width="100" Text="{Binding FirstName}" />
<Button Grid.Row="2" Height="30" Width="100" Content="Submit Me" Command="{Binding submitCommand}"/>
TextBox Grid.Row="3" Height="30" Width="100" Text="{Binding CopyName}" />
In View model make following changes...
public class Person:INotifyPropertyChanged{
private string _firstName;
private string _copyName=string.Empty;
public Person()
{
_firstName = "Ronaldo";
submitCommand = new RelayCommand(MyMethod, canExecuteMethod);
}
public string FirstName
{
get
{
return _firstName;
}
set
{
_firstName = value;
OnPropertyChanged("FirstName");
}
}
public string CopyName
{
get
{
return _copyName;
}
set
{
if (_copyName != value)
{
_copyName = value;
OnPropertyChanged("CopyName");
}
}
}
public ICommand submitCommand { get; set; }
private void MyMethod(object param)
{
MessageBox.Show("Welcome to Command Demo...");
CopyName = FirstName;
}
private bool canExecuteMethod(object parameter)
{
return true;
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(params string[] propertyNames)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
foreach (string propertyName in propertyNames) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
handler(this, new PropertyChangedEventArgs("HasError"));
}
}
}
You don't need CommandParameter here.
<Button Name="Submit" Grid.Row="2" Height="30" Width="100" Content="Submit Me" Command="{Binding submitCommand}" />
Add the Display property:
public string Display
{
get
{
return _display;
}
set
{
_display = value;
OnPropertyUpdated(Display);
}
}
Fix the binding in the second TextBox:
<TextBox x:Name="display" Grid.Row="3" Height="30" Width="100" Text="{Binding Display}" />
Update MyMethod:
private void MyMethod(object parameter)
{
MessageBox.Show("Welcome to Command Demo...");
Display = FirstName;
}
Here is how to copy text from one textBox to another.
this is dataContext behinde MainWindow
public class TestVM : INotifyPropertyChanged
{
public TestVM()
{
CopyCommand = new RelayCommand<string>(OnCopyExecuted);
}
private void OnCopyExecuted(string commandParameter)
{
TextUpdate = commandParameter;
}
private string _textUpdate;
public string TextUpdate
{
get { return _textUpdate; }
set
{
if (_textUpdate != value)
{
_textUpdate = value;
OnPropertyChanged();
}
}
}
public RelayCommand<string> CopyCommand { get; private set; }
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public virtual void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
Generic RelayCommand that can take parameters
public class RelayCommand<T> : ICommand
{
private Action<T> _executeMethod;
private Func<T, bool> _canExecuteMethod;
#region RelayCommand ctor
public RelayCommand(Action<T> executeMethod)
{
_executeMethod = executeMethod;
}
public RelayCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
{
_executeMethod = executeMethod;
_canExecuteMethod = canExecuteMethod;
}
#endregion
public void RaiseCanExecuteChanged()
{
CanExecuteChanged(this, EventArgs.Empty);
}
#region ICommand Members
bool ICommand.CanExecute(object parameter)
{
var Tparam = (T)parameter;
if (_canExecuteMethod != null)
return _canExecuteMethod(Tparam);
if (_executeMethod != null)
return true;
return false;
}
void ICommand.Execute(object parameter)
{
if (_executeMethod != null)
_executeMethod((T)parameter);
}
public event EventHandler CanExecuteChanged = delegate { };
#endregion
}
and MainWindow xaml just to show purpose
<Window.DataContext>
<local:TestVM />
</Window.DataContext>
<Grid>
<TextBox x:Name="txt1"
Height="35"
Width="150"
Margin="49,62,318,224" />
<TextBox Text="{Binding TextUpdate}"
Height="35"
Width="150"
Margin="313,62,54,226" />
<Button Command="{Binding CopyCommand}"
CommandParameter="{Binding ElementName=txt1,Path=Text}"
Content="Copy"
Grid.Row="0"
Margin="208,157,198,132" />
</Grid>
It's working. Now you can implement it as it fits your needs.
I have got a View who's DataContext is set to an Employee.
Further, the view uses a BindingGroup and Validation Rules.
At last the view has got 2 Buttons: Save and Cancel
Save: Validate the users input and in case of success, save the changes.
Cancel: Rollback the user input and restore the original values.
Until this point it works fine.
Now the last requirement and the problem:
For a better User Experience i would like to enable the save Button when the user begins to change data.
To achieve this, I bind the IsDirty Property of the BindingGroup to the Enabled Property of the Button.
Unfortunately it doesn't work. The binding seems to be correct, but the user interface does not recognize the change of IsDirty.
Who can i solve this problem?
My Model:
public class EmployeeModel:ModelBase
{
private int _nr;
private string _firstname;
private string _lastname;
public int Nr
{
get
{
return _nr;
}
set
{
_nr = value;
OnChanged(nameof(Nr));
}
}
public string Firstname
{
get
{
return _firstname;
}
set
{
_firstname = value;
OnChanged(nameof(Firstname));
}
}
public string Lastname
{
get
{
return _lastname;
}
set
{
_lastname = value;
OnChanged(nameof(Lastname));
}
}
}
ModelBase:
public class ModelBase:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnChanged(string propertyname)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
}
ValidationRule:
public class EmployeeValidationRule:ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
BindingGroup bindingGroup = (BindingGroup)value;
if (bindingGroup.Items.Count == 2)
{
EmployeeModel employee = (EmployeeModel)bindingGroup.Items[1];
string firstname = (string)bindingGroup.GetValue(employee, "Firstname");
string lastname = (string)bindingGroup.GetValue(employee, "Lastname");
if (firstname.Length == 0)
return new ValidationResult(false, "Firstname can not be empty.");
if (lastname.Length == 0)
return new ValidationResult(false, "Lastname can not be empty.");
}
return ValidationResult.ValidResult;
}
}
My ViewModel:
public class EmployeeViewModel
{
private EmployeeModel _employeeModel;
public EmployeeModel Employee
{
get
{
return _employeeModel;
}
set
{
_employeeModel = value;
}
}
public EmployeeViewModel()
{
LoadData();
}
private void LoadData()
{
//Employee = (from e in _context.Employee
// where e.Nr == 158
// select e).FirstOrDefault();
Employee = new EmployeeModel() { Firstname = "Billy", Lastname = "Wilder" };
}
public void Save()
{
//_context.SaveChanges();
}
}
At last the View:
<Window x:Class="WpfApplication3_Validation.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:WpfApplication3_Validation"
xmlns:vm="clr-namespace:WpfApplication3_Validation.ViewModel"
xmlns:vr="clr-namespace:WpfApplication3_Validation.ValidationRules"
mc:Ignorable="d"
Title="Employee" Height="250" Width="525"
Validation.ValidationAdornerSite="{Binding ElementName=lbErrors}" Loaded="Window_Loaded">
<Window.DataContext>
<vm:EmployeeViewModel/>
</Window.DataContext>
<Window.BindingGroup>
<BindingGroup x:Name="MyBindingGroup">
<BindingGroup.ValidationRules>
<vr:EmployeeValidationRule/>
</BindingGroup.ValidationRules>
</BindingGroup>
</Window.BindingGroup>
<Grid x:Name="gridMain">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Content="Nr:"/>
<TextBlock Grid.Column="1" Text="{Binding Employee.Nr}"/>
<Label Grid.Row="1" Content="Vorname:" Target="{Binding ElementName=tbFirstname}"/>
<TextBox Grid.Row="1" Grid.Column="1" x:Name="tbFirstname" Text="{Binding Employee.Firstname}"/>
<Label Grid.Row="2" Content="Nachname:" Target="{Binding ElementName=tbLastname}"/>
<TextBox Grid.Row="2" Grid.Column="1" x:Name="tbLastname" Text="{Binding Employee.Lastname}"/>
<Label Grid.Row="4" Grid.Column="0" x:Name="lbErrors" Content="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.ValidationAdornerSiteFor).(Validation.Errors)[0].ErrorContent}"
Foreground="Red" FontWeight="Bold"/>
<StackPanel Grid.Row="4" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
<TextBlock x:Name="tbIsDirty"/>
<Button x:Name="btn1" Content="IsDirty?" Click="btn1_Click"/>
<Button x:Name="btnSave" Content="Save1" Click="btnSave_Click" />
<Button x:Name="btnSave1" Content="Save2" Click="btnSave_Click" IsEnabled="{Binding ElementName=MyBindingGroup, Path=IsDirty}"/>
<Button x:Name="btnCancel" Content="Cancel" Click="btnCancel_Click"/>
</StackPanel>
</Grid>
Code Behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.MyBindingGroup.BeginEdit(); // Not really needed?
}
private void btnSave_Click(object sender, RoutedEventArgs e)
{
if (this.BindingGroup.CommitEdit())
{
EmployeeViewModel vm = (EmployeeViewModel)this.DataContext;
vm.Save();
}
}
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
this.BindingGroup.CancelEdit();
}
private void btn1_Click(object sender, RoutedEventArgs e)
{
tbIsDirty.Text = BindingGroup.IsDirty.ToString();
}
}
Due to the fact that BindingGroup.IsDirty does not Implement INotifyPropertyChanged, it's not a useful source for this type of databinding.
Possible solution:
- Implementing INotifyPropertyChanged in the view
- Creating a own IsDirty in the view, using INotifyPropertyChanged
- Adding an event handler for KeyUp, which sets my IsDirty in case of BindingGroup.IsDirty.
- Binding of Enabled to the new Property
Disadvantage: Need if implementation of INotifyPropertyChanged in the view.
Advantage: It works.
CodeBehind of View:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnChanged(string propertyname)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
private bool _isDirty;
public bool IsDirty
{
get
{
return _isDirty;
}
set
{
_isDirty = value;
OnChanged(nameof(IsDirty));
}
}
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.MyBindingGroup.BeginEdit(); // Not really needed?
gridMain.KeyUp += GridMain_KeyUp;
}
private void GridMain_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
if (this.MyBindingGroup.IsDirty)
{
IsDirty = true;
}
}
private void btnSave_Click(object sender, RoutedEventArgs e)
{
if (this.BindingGroup.CommitEdit())
{
EmployeeViewModel vm = (EmployeeViewModel)this.DataContext;
vm.Save();
IsDirty = false;
}
}
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
this.BindingGroup.CancelEdit();
IsDirty = false;
}
}
Further improvements:
Now i moved IsDirty to my ViewModel, so I don't have to implement INPC in the view. Another advantage is, that in this way, Commands can consume the property and finally i don't have to use databinding for the enabled Property, because i get it over the command.
I have 3 buttons in a user control, I would like to show and hide one button from the WPF application or from the user control. Its not working for me. I have implemented INotifyPropertChanged interface to notify the View. Please check it.
<UserControl x:Class="WPFUserControl.UserControl1"
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"
mc:Ignorable="d"
xmlns:vis="clr-namespace:WPFUserControl"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<vis:BoolToVisibilityConverter x:Key="BoolToVis" ></vis:BoolToVisibilityConverter>
</UserControl.Resources>
<Grid>
<Button Content="Button1" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75"/>
<Button Content="Button2" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="106,0,0,0"/>
<Button Content="ShowHide" Visibility="{Binding IsShowHideVisible, Converter={StaticResource BoolToVis}, ConverterParameter=False}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="215,0,0,0"/>
</Grid>
public partial class UserControl1 : UserControl, INotifyPropertyChanged
{
private bool isShowHideVisible;
public bool IsShowHideVisible
{
get { return isShowHideVisible; }
set
{
if(isShowHideVisible!=value)
{
isShowHideVisible = value;
}
}
}
public UserControl1()
{
InitializeComponent();
// IsShowHideVisible = false;
}
private void OnPropertyChange(string pPropertyName)
{
if(PropertyChanged!=null)
{
PropertyChanged(this, new PropertyChangedEventArgs(pPropertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
In the setter of your IsShowHideVisible-Property you have to call OnPropertyChanged("IsShowHideVisible") right after isShowHideVisible = value;.
Your property then looks like:
public bool IsShowHideVisible
{
get { return isShowHideVisible; }
set
{
if(isShowHideVisible!=value)
{
isShowHideVisible = value;
OnPropertyChanged("IsShowHideVisible");
}
}
}
If you're using .net 4.5 or higher you can rewrite your OnPropertyChanged-Method like:
private void OnPropertyChange([CallerMemberName]string pPropertyName = null)
{
if(PropertyChanged!=null)
{
PropertyChanged(this, new PropertyChangedEventArgs(pPropertyName));
}
}
Than in your Property you only have to call OnPropertyChanged(); instead of OnPropertyChanged("IsShowHideVisible");
After adding this.DataContext=this inside the constructor and OnPropertyChange("IsShowHideVisible") inside the set field , its working.
public partial class UserControl1 : UserControl, INotifyPropertyChanged
{
private bool isShowHideVisible;
public bool IsShowHideVisible
{
get { return isShowHideVisible; }
set
{
if(isShowHideVisible!=value)
{
isShowHideVisible = value;
OnPropertyChange("IsShowHideVisible");
}
}
}
public UserControl1()
{
InitializeComponent();
this.DataContext=this;
}
private void OnPropertyChange(string pPropertyName)
{
if(PropertyChanged!=null)
{
PropertyChanged(this, new PropertyChangedEventArgs(pPropertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
I have used many ComboBoxes in my applications and all of them are working without any problem. But, I can't find the problem now. I have set SelectedValuePath to "Tag" property. But the property not updating after changing the ComboBox selected item. I have read other StackOverflow questions, but nontheless helped.
It is xaml:
xmlns:vms="clr-namespace:SilverlightApplication1"
<UserControl.DataContext>
<vms:MainViewModel />
</UserControl.DataContext>
<Grid x:Name="LayoutRoot" Background="White">
<ComboBox Width="100" VerticalAlignment="Center" FontFamily="Segoe UI"
Height="30" Margin="0,5,0,0" HorizontalAlignment="Left"
SelectedValue="{Binding SelectedDifStatusComparer, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="Tag">
<ComboBox.Items>
<ComboBoxItem Tag="H" >High</ComboBoxItem>
<ComboBoxItem Tag="L" >Low</ComboBoxItem>
<ComboBoxItem Tag="E" >Equal</ComboBoxItem>
</ComboBox.Items>
</ComboBox>
</Grid>
And here is the ViewModel:
public class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private string _selectedDifStatusComparer = "";
private string SelectedDifStatusComparer
{
get { return _selectedDifStatusComparer; }
set
{
_selectedDifStatusComparer = value;
MessageBox.Show(_selectedDifStatusComparer);
OnPropertyChanged("SelectedDifStatusComparer");
}
}
public MainViewModel()
{
SelectedDifStatusComparer = "E"; // It is working, the MessageBox is apperaing
}
}
Your property is private. Change it to public and it should work.
public class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private string _selectedDifStatusComparer = "";
public string SelectedDifStatusComparer
{
get { return _selectedDifStatusComparer; }
set
{
_selectedDifStatusComparer = value;
MessageBox.Show(_selectedDifStatusComparer);
OnPropertyChanged("SelectedDifStatusComparer");
}
}
public MainViewModel()
{
SelectedDifStatusComparer = "E"; // It is working, the MessageBox is apperaing
}
}
Your property is private. Change it to public and it should work.
I have this custom wpf user control:
ShowCustomer.xaml:
<UserControl x:Class="TestControlUpdate2343.Controls.ShowCustomer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<TextBlock Text="{Binding Message}"/>
</Grid>
</UserControl>
ShowCustomer.xaml.cs:
using System.Windows.Controls;
using System;
using System.ComponentModel;
namespace TestControlUpdate2343.Controls
{
public partial class ShowCustomer : UserControl, INotifyPropertyChanged
{
#region ViewModelProperty: Message
private string _message;
public string Message
{
get
{
return _message;
}
set
{
_message = value;
OnPropertyChanged("Message");
}
}
#endregion
public ShowCustomer()
{
InitializeComponent();
DataContext = this;
Message = "showing test customer at: " + DateTime.Now.ToString();
}
#region INotifiedProperty Block
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
And I display it from this XAML:
Window1.xaml:
<Window x:Class="TestControlUpdate2343.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:TestControlUpdate2343.Controls"
Title="Window1" Height="300" Width="300">
<StackPanel HorizontalAlignment="Left" Margin="10">
<controls:ShowCustomer x:Name="ShowCustomerControl" Margin="0 0 0 10"/>
<Button Content="Refresh Control"
Click="Button_RefreshControls_Click"
Margin="0 0 0 10"/>
</StackPanel>
</Window>
And I would like to update the control (i.e. in this example show the current time) from my event handler in code behind:
using System.Windows;
namespace TestControlUpdate2343
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void Button_RefreshControls_Click(object sender, RoutedEventArgs e)
{
//ShowCustomerControl.Refresh()???
}
}
}
How can I force a refresh of my custom control from code behind, or force it to reload somehow so when I click the button it shows the current time?
in Window1.xaml.cs -
private void Button_RefreshControls_Click(object sender, RoutedEventArgs e)
{
ShowCustomerControl.Refresh();
}
in ShowCustomer.xaml.cs -
public ShowCustomer()
{
InitializeComponent();
DataContext = this;
Refresh();
}
public void Refresh()
{
Message = "showing test customer at: " + DateTime.Now.ToString();
}
Hope this helps!!
Or have a LastUpdate property on ShowWindow and set that, which then regenerates the Message property.