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.
Related
I have a winform called form1 which has tabcontrol with some tabpages and one button on clicking of which I open another form called form2. I want to add tabpage to form1 tabcontrol on click of button which is present on form2.
Assumed that you have not created a tabcontrol at runtime in the Firstform.
In FirstForm.cs
private void button1_Click(object sender, EventArgs e)
{
SecondForm obj = new SecondForm(this);
obj.Show();
}
public void addTabpage()
{
TabPage tbpg = new TabPage();
tbpg.Text = "New tabpage";
tabControl1.TabPages.Add(tbpg);
this.BringToFront();
}
In SecondForm.cs, change the constructor as follows
static FirstForm objpub;
public SecondForm(FirstForm obj)
{
InitializeComponent();
objpub = obj;
}
private void button1_Click(object sender, EventArgs e)
{
if (objpub != null)
{
objpub.addTabpage();
}
}
If this answer does not meet your problem, then provide your code.
Cheers !
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.
}
When button1 gets tapped by the stylus test method gets called twice, even though I am setting the Handled property in the stylusdown event. Is there a way to have the stylus event not propegate a secondary button click event?
namespace DialogTest
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
test(sender, e);
}
private void button1_StylusDown(object sender, StylusDownEventArgs e)
{
test(sender, e);
e.Handled = true;
}
private void test(object e, EventArgs env)
{
Console.WriteLine(e.ToString(), env.ToString());
Console.WriteLine("clicking");
}
}
If you look at this MSDN Input overview documentation. you will see the fact the both events are called.
From above link:
Because the stylus can act as a mouse, applications that support only mouse input can still obtain some level of stylus support automatically. When the stylus is used in such a manner, the application is given the opportunity to handle the appropriate stylus event and then handles the corresponding mouse event. In addition, higher-level services such as ink input are also available through the stylus device abstraction.
Since it does give you the order the events are called you can create a Boolean variable, set it in the StylusDown EventHandler, then check in your Button_Click EventHandler if it is true, set it to false then exit the Handler.
something like this.
public partial class Window1 : Window
{
bool StylusDown;
public Window1()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
if(StylusDown)
{
StylusDown=false;
return;
}
test(sender, e);
}
private void button1_StylusDown(object sender, StylusDownEventArgs e)
{
StylusDown =true;
test(sender, e);
}
private void test(object e, EventArgs env)
{
Console.WriteLine(e.ToString(), env.ToString());
Console.WriteLine("clicking");
}
}
There may be a better way of accomplishing this, but this is was the first thing that came to mind.
MouseEventArgs has a property called StylusDevice that will be not null if the event originated from a stylus or touch event.
private void button1_Click(object sender, MouseButtonEventArgs e)
{
if (e.StylusDevice != null) return;
...
}
I have a user control that contains a ListBox.
I want to expose a SelectionChanged event on my user control that wraps the listBox.SelectionChanged event.
So that, when the listbox item selection changes, my own custom event on the user control also gets fired after that...
How would I do that?
Any sample would be appreciated.
Thanks!
I'm not sure wrapping is the best approach, even if you could wrap it. I'd suggest just defining your own event, and fire your own event in the handler hooked to listBox.SelectionChanged. You can then pass on any data from the original listbox event to your own event.
Added sample:
public partial class MainWindow : Window
{
public delegate void CustomSelectionChangedEventHandler(object sender, SelectionChangedEventArgs e);
public event CustomSelectionChangedEventHandler CustomSelectionChanged;
public MainWindow()
{
InitializeComponent();
listBox1.SelectionChanged += delegate(object sender, SelectionChangedEventArgs e)
{
OnCustomSelectionChanged(e);
};
}
void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
OnCustomSelectionChanged(e);
}
//We'll use the system defined SelectionChangedEventArgs type instead of creating a derived EventArgs class
protected virtual void OnCustomSelectionChanged(SelectionChangedEventArgs e)
{
if (CustomSelectionChanged != null)
CustomSelectionChanged(this, e);
}
}
Further reading:
http://msdn.microsoft.com/en-us/library/edzehd2t.aspx
http://msdn.microsoft.com/en-us/library/17sde2xt.aspx
If you want your custom event on your UserControl to bubble up the visual tree you should expose it as a RoutedEvent. In your .xaml.cs file you'll need to register the event as a routed event and then implement a custom handler and event args class.
XAML:
<UserControl x:Class="WpfApplication1.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<ListView Name="myListView" SelectionChanged="OnSelectionChanged_"/>
</Grid>
</UserControl>
Code:
public partial class MyUserControl : UserControl
{
public delegate void CustomSelectionChangedEventHandler(object sender, SelectionChangedRoutedEventArgs args);
public static readonly RoutedEvent CustomSelectionChangedEvent = EventManager.RegisterRoutedEvent(
"CustomSelectionChanged", RoutingStrategy.Bubble, typeof(CustomSelectionChangedEventHandler), typeof(MyUserControl));
public event RoutedEventHandler CustomSelectionChanged
{
add { AddHandler(CustomSelectionChangedEvent, value); }
remove { RemoveHandler(CustomSelectionChangedEvent, value); }
}
public MyUserControl()
{
InitializeComponent();
}
private void OnSelectionChanged_(object sender, SelectionChangedEventArgs e)
{
RaiseEvent(new SelectionChangedRoutedEventArgs(myListView, CustomSelectionChangedEvent, e.AddedItems, e.RemovedItems));
}
}
public class SelectionChangedRoutedEventArgs : RoutedEventArgs
{
public IList AddedItems { get; set; }
public IList RemovedItems { get; set; }
public SelectionChangedRoutedEventArgs(object source, RoutedEvent routedEvent, IList addedItems, IList removedItems)
: base(routedEvent, source)
{
AddedItems = addedItems;
RemovedItems = removedItems;
}
}
The caller of your control would then provide an event handler for the CustomSelectionChanged event with the signature of:
private void OnCustomSelectionChanged(object sender, SelectionChangedRoutedEventArgs e) { }
I’d like to load a page into frame with key binding using ‘Ctrl’ and ‘H’ buttons from a keyboard. I can load page. It is working now. I am wondering if I can just override UriSource link with what it is now into frame. I assign UriSources in XML and I need to override one instance instead of introducing new UriSource to keep the index not changed. Any ideas? Thank you in advance!
public partial class MainWindow : Window
{
public static RoutedUICommand LoadShareSelectedCommand = new RoutedUICommand();
public MainWindow()
{
InitializeComponent();
this.CommandBindings.Add(new CommandBinding(LoadShareSelectedCommand, LoadShareSelectedCommandExecuted));
KeyGesture kg = new KeyGesture(Key.H, ModifierKeys.Control);
InputBinding ib = new InputBinding(LoadShareSelectedCommand, kg);
this.InputBindings.Add(ib);
}
private void LoadShareSelectedCommandExecuted(object sender, ExecutedRoutedEventArgs e)
{
this.ContentFrame.NavigationService.Navigate(new Uri("Pages/SharesSelected.xaml", UriKind.Relative));
}
private void LoadShareSelectedCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void NavShareSelected(object sender, RoutedEventArgs e)
{
this.ContentFrame.NavigationService.Navigate(new Uri("Pages/SharesSelected.xaml", UriKind.Relative));
}
}