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
}
}
Related
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 want to execute certain code in view if something happens in view model . I have looked into Prism event aggregator but I havent got success with prism 5. If there is more easier method to do so it will be helpful.Any blog or same code regarding this will also work
As Ed Plunkett says, the thing to do is listen for DataContextChanged in your view, as this is how View's are connected to ViewModels.
Here's an example:
public partial class MyView : UserControl
{
public MyView ()
{
DataContextChanged += MyView_DataContextChanged;
}
private void MyView_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
//new ViewModel has been set.
MyViewModel myViewModel = e.NewValue as MyViewModel;
if (myViewModel != null)
{
//check for property changes
myViewModel.PropertyChanged += MyViewModel_PropertyChanged;
//custom event for specific update
myViewModel.MyCustomEventTriggered += MyViewModel_MyCustomEventTriggered
}
}
private void MyViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
//do your logic
}
private void MyViewModel_MyCustomEventTriggered(object sender, MyCustomEventArgs e)
{
//do your logic
}
}
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 have some concept question here. I know how to select all text in TextBox or in PasswordBox. Via GotKeyboardFocus and PreviewMouseLeftButtonDown events, you know. This works fine.
XAML:
PreviewMouseLeftButtonDown="PasswordOnPreviewMouseDown"
GotKeyboardFocus="SelectAllPassword"
CodeBehind
private void SelectAllPassword(Object sender, RoutedEventArgs e)
{
var pb = (sender as PasswordBox);
if (pb != null)
pb.SelectAll();
}
private void PasswordOnPreviewMouseDown(Object sender, MouseButtonEventArgs e)
{
var pb = (sender as PasswordBox);
if (pb != null)
if (!pb.IsKeyboardFocusWithin)
{
e.Handled = true;
pb.Focus();
}
}
But question is - why this doesn't work?
XAML:
PreviewMouseLeftButtonDown="PasswordOnPreviewMouseDown"
CodeBehind:
private void PasswordOnPreviewMouseDown(Object sender, MouseButtonEventArgs e)
{
_txtPassword.SelectAll();
e.Handled = true;
}
Where _txtPassword - TextBox or PasswordBox control. So why I'm enforsed to Focus text control?
Actually, the selection is working.
You may feel that the text is not selected because it's not visually highlighted, but that's because the TextBox is not focused.
Try giving focus to your TextBox with the Tab key, you'll see the whole text highlighted.
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.
}