I have a ContentControl element whose ContentTemplate is determined at run time from the Resource Dictionary. In the datatemplate I have a visual (Convas) and what I want is to also have a button in datatemplate which when clicked should print the visual element(canvas).
As I said that the DateTemplate is inside the Resource Dictionary so How can I write a Code on Click Event of that button and where it should be?
Any response would be much appreciated.
Sounds like you can use the Button.Click attached event. Just add it to the ContentControl.
<ContentControl
Button.Click="Button_Click"
ContentTemplate="<template with a button>"
/>
and the handler:
private void Button_Click(object sender, RoutedEventArgs e)
{
}
If you have multiple buttons in your template, you can use e.Source to figure it out. And I think you can use MouseButtonEventArgs instead.
Related
I am trying to bind the IsEnabled property of a button to properties of the window's CollectionViewSource. I am doing this to implement First/Previous/Next/Last buttons and want the First and Previous to be disabled when the view is on the first item etc.
I have the collection view source set up, UI controls binding to it correctly, with access to its view in code so the click event handlers work fine in navigating through the view.
<CollectionViewSource x:Key="cvMain" />
The DockPanel is the root element of the window
<DockPanel DataContext="{StaticResource cvMain}">
FoJobs is an observable collection, cvJobs is a CollectionView that I use in the button's click handler
private void Window_Loaded(object sender, RoutedEventArgs e) {
((CollectionViewSource)Resources["cvMain"]).Source = FoJobs;
cvJobs = (CollectionView)((CollectionViewSource)Resources["cvMain"]).View;
}
I have tried this but get a binding error "BindingExpression path error: '' property not found on 'object' ''ListCollectionView'"
<Button Name="cbFirst" Click="cbMove_Click" IsEnabled="{Binding Source={StaticResource cvMain}, Converter={StaticResource CurrPos2BoolConverter}}" />
I am trying to do with a converter first but figure a style with triggers would be more efficient, but cant get access to the collection view. Even though the underlying datacontext is set to a collection view source, the binding is passed to the converter as the view's source (if I dont explicity set the binding's Source, as above), which has no currency properties (CurrentPosition, Count etc).
Any help would be greatly appreciated.
Why don't you use a RoutedCommand for this(even if you don't use MVVM that is)?
say something like:
<Button x:Name="nextButton"
Command="{x:Static local:MainWindow.nextButtonCommand}"
Content="Next Button" />
and in your code-behind:
public static RoutedCommand nextButtonCommand = new RoutedCommand();
public MainWindow() {
InitializeComponent();
CommandBinding customCommandBinding = new CommandBinding(
nextButtonCommand, ExecuteNextButton, CanExecuteNextButton);
nextButton.CommandBindings.Add(customCommandBinding); // You can attach it to a top level element if you wish say the window itself
}
private void CanExecuteNextButton(object sender, CanExecuteRoutedEventArgs e) {
e.CanExecute = /* Set to true or false based on if you want button enabled or not */
}
private void ExecuteNextButton(object sender, ExecutedRoutedEventArgs e) {
/* Move code from your next button click handler in here */
}
You can also apply one of the suggestions from Explicitly raise CanExecuteChanged() to manually re-evaluate Button.isEnabled state.
This way your encapsulating logic relating to the button in one area.
In this question I asked about adding TabItems dynamically to a TabControl
the ItemsSource are from ObservableCollection<Village>..
My question is if added a button to any TabItem, this button will have the DataContext of its container TabItem, how could I implement the Click event for this button?
If you have added the Button to the DataTemplate, then on your Button_Click method you can easily get the 'Village' datacontext.
void Button_Click(object sender, RoutedEventArgs e)
{
Village clickedVillage = ((Button)sender).DataContext as Village;
//Do whatever you want to do with the Village
}
But again, the above solution is not the best way to go for this problem. MVVM pattern would expect a ICommand in your Village (Or its container class) and you will bind that command to the Button.Command property so there wont be any code-behind at all. Or in other words your XAML will be more cleaner and ViewModel will get more self-contained in terms of properties and actions.
Is there any way for me to do this?
You can tell when the VerticalOffset changes by adding a handler to the ScrollViewer.ScrollChanged event to your TextBox. Something like this:
<TextBox AcceptsReturn="True" ScrollViewer.ScrollChanged="TextBox_ScrollChanged" />
The TextBox uses a ScrollViewer internally, so it's ScrollChanged event will bubble up to the TextBox (where you can handle it). The event arguments include information about what changed, such as the VerticalChange (the amount that the control has scrolled vertically).
private void TextBox_ScrollChanged(object sender, ScrollChangedEventArgs e) {
System.Diagnostics.Debug.WriteLine(string.Format("************ {0}", e.VerticalChange));
}
Can i set a mouselistener (Clicked) in WPF?
Simple,
Just a Click attribute to your xaml control
Assign it a handler
Define the handler in your xaml.cs
In your xaml,
<Button Click="Button_Click"></Button>
In your xaml.cs,
private void Button_Click(object sender, RoutedEventArgs e)
{
//What should be done when you click the control
}
There are loads of mouse events available. Check MSDN for the list of mouse events supported in WPF
If te user clicked where?
If you have a button(or window or pretty much anything else) you simpy add the MouseDown() eventhandler....
I have in my application a data template that has a few buttons.
I want those buttons' even handler to be fired in the current page (I am using this template in many pages) rather than in the Application.xaml.vb/cs file, since I want different actions on each page.
I hope I am clear.
You can use commanding to achieve this. Have the Buttons in the DataTemplate execute specific Commands:
<Button Command="{x:Static MyCommands.SomeCommand}"/>
Then have each view that uses that DataTemplate handle the Command:
<UserControl>
<UserCommand.CommandBindings>
<CommandBinding Command="{x:Static MyCommands.SomeCommand}"
Executed="_someHandler"/>
</UserCommand.CommandBindings>
</UserControl>
EDIT after comments: Once you have created a code-behind for your ResourceDictionary as per these instructions, you can simply connect events in the usual fashion:
In MyResources.xaml:
<ListBox x:Key="myListBoxResource" ItemSelected="_listBox_ItemSelected"/>
Then in MyResources.xaml.cs:
private void _listBox_ItemSelected(object sender, EventArgs e)
{
...
}
If you use events and not commands, then in your Click event handler just write
private void Button_Click(object sender, RoutedEventArgs e)
{
var dataItem = (FrameworkElement)sender).DataContext;
// process dataItem
}