I have a DatePicker managing SelectedDateChanged event:
<DatePicker Name="myDatePicker" SelectedDateChanged="myDatePicker_SelectedDateChanged" />
If I choose a date with the calendar, SelectedDateChanged event is fired once. If I change date manually, SelectedDateChanged event is fired twice.
I found other people speaking about the same problem and resolving it by setting a flag when event is first fired, and test the flag value.
I would like to find a different approach to solve my issue, without using a flag.
First time it fires for DatePicker SelectedDate and second time for Calendar SelectedDate... So it's not error, it's strange logic.
I managed to do what I wanted.
When form is loaded, I added GotFocus and LostFocus events to the DatePicker TextBox (using Template.FindName method). I also added CalendarOpened and CalendarClosed event on the DatePicker.
It's not very elegant and if you think there is a better way, fell free to comment, I am a beginner in WPF...
public partial class MainWindow : Window
{
private TextBox txtDtPicker;
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
txtDtPicker = (TextBox)myDatePicker.Template.FindName("PART_TextBox", myDatePicker);
myDatePicker.CalendarOpened += new RoutedEventHandler(myDatePicker_CalendarOpened);
myDatePicker.CalendarClosed += new RoutedEventHandler(myDatePicker_CalendarClosed);
txtDtPicker.GotFocus += new RoutedEventHandler(txtDtPicker_GotFocus);
txtDtPicker.LostFocus += new RoutedEventHandler(txtDtPicker_LostFocus);
}
private void txtDtPicker_GotFocus(object sender, RoutedEventArgs e)
{
myDatePicker.SelectedDateChanged += new EventHandler<SelectionChangedEventArgs>(myDatePicker_SelectedDateChanged);
}
private void txtDtPicker_LostFocus(object sender, RoutedEventArgs e)
{
myDatePicker.SelectedDateChanged -= new EventHandler<SelectionChangedEventArgs>(myDatePicker_SelectedDateChanged);
}
private void myDatePicker_CalendarOpened(object sender, RoutedEventArgs e)
{
myDatePicker.SelectedDateChanged += new EventHandler<SelectionChangedEventArgs>(myDatePicker_SelectedDateChanged);
}
private void myDatePicker_CalendarClosed(object sender, RoutedEventArgs e)
{
myDatePicker.SelectedDateChanged -= new EventHandler<SelectionChangedEventArgs>(myDatePicker_SelectedDateChanged);
// When calendar is closed after a date selection, unfocus and focus again txtDtPicker. If not done, SelectedDateChanged event will not fire if date is changed manually just after changed was done with calendar
myDatePicker.Focus();
txtDtPicker.Focus();
}
int iNbTimesEventOccurs = 0;
private void myDatePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
{
// Remove event to prevent it to happen twice
myDatePicker.SelectedDateChanged -= new EventHandler<SelectionChangedEventArgs>(myDatePicker_SelectedDateChanged);
// Just to control event is not fired several times
iNbTimesEventOccurs++;
textBlock1.Text = "Nb times event occurs: " + iNbTimesEventOccurs;
}
}
Related
I'm working on WPF project where I populate a tree view (MainWindow.xaml)using a Class called SampleTreeItem (SampleTreeView class). This tree view shows files from the selected folder. when user clicks the tree item (mainWindow.cs), the code in the background opens the file, serializes it and extract the data from it.
Now I'm adding a checkbox to this tree through the class using header template.
There is event called OnItemSelected (in Mainwindow.cs) which gets fired when I select item from tree view.
I'm trying to handle the click event of the checkbox in Sampletree.cs and I want to fire OnItemSelected from mainwindow.cs when user clicks on the check box.
MainWindow.xaml.cs
private void filesTreeView_OnItemSelected(object sender, RoutedEventArgs e)
{
SampleFileTreeItem treeViewItem = e.Source as SampleFileTreeItem;
if (treeViewItem == null)
return;
OpenSampleFile(treeViewItem.FilePath);
}
This is the click event in the SampleTree.cs file.
public void CompareSamples_Click(object sender, RoutedEventArgs e)
{
//RoutedEvent routedEvent = e.RoutedEvent;
//e.Handled= true;
//e.Source = this;
//RoutedEventArgs args = new RoutedEventArgs(routedEvent, e);
RoutedEvent routedEvent = TreeView.SelectedItemChangedEvent;
e.Source = this;
RoutedEventArgs args = new RoutedEventArgs(routedEvent, e);
if (compareSamplesCheckbox.IsChecked == true)
{
OnSelected(args);
}
else
{
//object sender, RoutedEventArgs e
}
}
I don't know what I'm missing here but I cant fire OnItemSelected (mainWinodw) from SampleTree.cs.
Let me know if anyone has any thoughts on it. Appreciate any help.
I assume, that OnSelected(..) is an event handler. So in your code you need not to call an event handler, but to raise an event for the UIElement:
public void CompareSamples_Click(object sender, RoutedEventArgs e)
{
RoutedEvent routedEvent = TreeView.SelectedItemChangedEvent;
e.Source = this;
RoutedPropertyChangedEventArgs<object> args = new RoutedPropertyChangedEventArgs<object>(oldVal, newVal, routedEvent);
if (compareSamplesCheckbox.IsChecked == true)
{
yourTreeView.RaiseEvent(args);
}
else
{
//object sender, RoutedEventArgs e
}
}
I am trying to display the selection from a combobox in a textbox on a different page when a button is clicked. I thinking of using NavigationService, but I am not sure if that is the right way to go or not. In this part of the code I am getting the correct value and for testing I am displaying in messagebox, and that is working.
private void Button_Click(object sender, RoutedEventArgs e)
{
itemSelection = SubItemBox.Text;
NavigationService.Navigate(
new Uri("/Display.xaml?Message=" + itemSelection,
UriKind.Relative)
);
MessageBox.Show(itemSelection);
}
I am having an issue figuring out where to go next, I can't figure out how to get the itemSelection to dispaly in Display.xaml
namespace CateringDisplay
{
public partial class Display : Page
{
string itemSelection;
public Display()
{
InitializeComponent();
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
}
}
}
Any help would be appreciated as I am trying to learn WPF
Instead of using navigation, you could try the Event Aggregator (https://msdn.microsoft.com/en-us/library/ff921122.aspx):
You define an event:
public class SelectionChangedEvent : PubSubEvent<string> { }
You subscribe to the event in the Display Page
public partial class Display : Page
{
string itemSelection;
public Display()
{
InitializeComponent();
IEventAggregator eventAggregator = Locator.GetInstance<IEventAggregator>();
eventAggregator.GetEvent<SelectionChangedEvent>().Subscribe(OnSelectionChanged);
}
private void OnSelectionChanged(string obj)
{
itemSelection = obj;
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
}
}
The event handler updates your item selection using the event payload. Finally you fire the event from the button click event handler:
private void Button_Click(object sender, RoutedEventArgs e)
{
itemSelection = SubItemBox.Text;
IEventAggregator eventAggregator = Locator.GetInstance<IEventAggregator>();
eventAggregator.GetEvent<SelectionChangedEvent>().Publish(itemSelection);
MessageBox.Show(itemSelection);
}
Hope it helps.
I got a problem with usercontrol like this:
I have a formA contain 1 usercontrol with name UC_wrap
and UC_wrap contain a usercontrol with name UC_child
In UC_child contain : a button add, a button edit, a button delete and 1 textbox
but I don't know how do I create event for each button on formA?
please, Somebody help me !!!!
You can rig UC_Wrap with an event that forwards any events it receives from the button to whoever is subscribed to it.
partial class UC_Wrap : Control
{
public event EventHandler AddButtonClick
{
add { addButton.Click += value; }
remove { addButton.Click -= value; }
}
// etc
}
Then the UC_Control can forward those events
partial class UC_Control : Control
{
public event EventHandler AddButtonClickedInWrap
{
add { ucWrap.AddButtonClick += value; }
remove { ucWrap.AddButtonClick -= value; }
}
// etc
}
Then finally at the FormA level you can subscribe to the event and handle it.
partial class FormA : Form
{
protected override void OnLoad()
{
ucControl.AddButtonClickedInWrap += ActuallyDoSomething;
}
private void ActuallyDoSomething(object sender, EventArgs e)
{
// do something
}
}
That's probably the best way to do it. The only simpler way I can think of is to make each sub control public, but that has the major downside of exposing far more than is needed.
Try this
//UC_child - child user control code
public event EventHandler addClick;
public event EventHandler editClick;
public event EventHandler deleteClick;
//call above event in each button click ie.
private void btnAdd_Click(object sender, EventArgs e)
{
if (addClick != null)
addClick(sender, e);
}
//Do same for other edit and delete button
//UC_wrap- UC_wrap usercontrol code
//Hand UC_Child event in UC_wrap
//Create event again in UC_wrap
public event EventHandler addClick;
public event EventHandler editClick;
public event EventHandler deleteClick;
private void UC_Child_Load(object sender, EventArgs e)
{
UC_Child1.addClick += new EventHandler(add_Click);
//Do same for other edit and delete button
}
private void add_Click(object sender, EventArgs e)
{
if (addClick != null)
addClick(sender, e);
}
//formA-This is your form code
private void formA_Load(object sender, EventArgs e)
{
UC_wrap1.addClick += new EventHandler(add_Click);
//Do same for other edit and delete button
}
private void add_Click(object sender, EventArgs e)
{
//Place your code here.
}
I need a mouse click event in my silver light project and I know we need to simulate it ourself if the object is not button. lets say I want mouseclick for my img...
How exactly can we track time between mousedown and mouseup and say if the time between them is less than 300m, we have a mouse click?
Handle the MouseLeftButtonDown and MouseLeftButtonUp events for your image.
private DateTime? startClick;
private void image1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
startClick = DateTime.Now;
}
private void image1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var clickDuration = DateTime.Now - startClick;
if (startClick != null && clickDuration < TimeSpan.FromMilliseconds(300))
{
MessageBox.Show("Less than 300ms!");
}
startClick = null;
}
How I can show or hide a groupbox from xaml.cs. I try to do this in the checkbox's event:
private void cbDaily_Checked(object sender, RoutedEventArgs e)
{
gbCalendar.Visibility = Visibility.Visible;
}
But this don't work.
It must be work on checked/unchecked events of checkbox like this way :
private void chkTest_Checked(object sender, RoutedEventArgs e)
{
grpTest.Visibility = System.Windows.Visibility.Visible;
}
private void chkTest_Unchecked(object sender, RoutedEventArgs e)
{
grpTest.Visibility = System.Windows.Visibility.Hidden;
}
It is working fine in my sample application. Can you please give more details of your problem, so I can have better idea. Is event fired properly ? Make sure name of groupbox in code behind is correct or not ?