I want to make several buttons with the same click function but different parameter. Like this
XAML:
<Button Click="MyClickFunction(1)" Content="MyFunc(1)"/>
<Button Click="MyClickFunction(2)" Content="MyFunc(2)"/>
<Button Click="MyClickFunction(3)" Content="MyFunc(3)"/>
<Button Click="MyClickFunction(4)" Content="MyFunc(4)"/>
C#:
private void MyClickFunction(object sender, RoutedEventArgs e, int myParam)
{
//do something with parameter e.g. MessageBox.Show()
MessageBox.Show(myParam.ToString());
}
How to I pass the parameter in xaml tag or I will have to do it other ways?
Use Tag property in the button. Like this:
<Button Click="MyClickFunction" Tag="1" Content="MyFunc(1)"/>
<Button Click="MyClickFunction" Tag="2" Content="MyFunc(2)"/>
<Button Click="MyClickFunction" Tag="3" Content="MyFunc(3)"/>
<Button Click="MyClickFunction" Tag="4" Content="MyFunc(4)"/>
And in the code behind:
private void MyClickFunction(object sender, RoutedEventArgs e)
{
var tag = ((Button)sender).Tag;
MessageBox.Show(tag.ToString());
}
Related
I have a window that shows an open lock.
When the user clicks a button the lock must change to closed, wait a second and then close the windows.
How can I do that using WPF?
Here is my initial xaml:
<Button Grid.Row="2" BorderThickness="0" Background="Transparent" Margin="32"
IsTabStop="False" Click="BtnUnlockClick">
<Button.Content>
<Grid>
<Image Grid.Row="1" Source="/Common.Wpf;component/images/unlocked.png" Visibility="Visible" Name="imgUnlocked"/>
<Image Grid.Row="1" Source="/Common.Wpf;component/images/locked.png" Visibility="Collapsed" Name="imgLocked"/>
</Grid>
</Button.Content>
</Button>
and C#:
private void BtnUnlockClick(object sender, RoutedEventArgs e)
{
//do stuff here
}
Put only one Image element into the Button's Content.
<Button Click="BtnUnlockClick" ...>
<Image Source="/Common.Wpf;component/images/unlocked.png"/>
</Button>
In the Click event handler change its Source, wait a second, then close the Window. The handler method must be declared async.
private async void BtnUnlockClick(object sender, RoutedEventArgs e)
{
var image = (Image)((Button)sender).Content;
image.Source = new BitmapImage(
new Uri("pack://application:,,,/Common.Wpf;component/images/locked.png"));
await Task.Delay(1000);
Close();
}
In regular WPF you can have a button inside another button, and to prevent both button events being raised when you click the inner button, you can have the following XAML (As per this question):
<Button Click="OuterClick">
<Grid>
<SomeOtherContent />
<Button Click="InnerClick" />
</Grid>
</Button>
And then in the code-behind use the Handled property on the event so that OuterClick is not raised when the inner button has been clicked:
private void OuterClick(object sender, RoutedEventArgs e) {
// Do something
}
private void InnerClick(object sender, RoutedEventArgs e) {
// Do something else
e.Handled = true;
}
However, following the usual Caliburn.Micro conventions you'll have the following XAML:
<Button x:Name="OuterClick">
<Grid>
<SomeOtherContent />
<Button x:Name="InnerClick" />
</Grid>
</Button>
With this in the ViewModel:
private void OuterClick() {
// Do something
}
private void InnerClick() {
// Do something else
}
How can I make sure that not both InnerClick() and OuterClick() are raised when I click the InnerButton?
EDIT: Or, what other kind of controls can I use instead?
<StackPanel cal:Message.Attach="[Event MouseDown]=[Action OuterClick()]">
<StackPanel Orientation="Horizontal">
<SomeotherContent />
<Button x:Name="InnerClick" />
</StackPanel>
</StackPanel>
In Your viewmodel
public void OuterClick()
{
//Do something
}
public void InnerClick()
{
//Do something
}
use stackpanel and apply event for that one.
This will help you.
I have following code in WPF:
private void BtnTicketPrice_Click(object sender, RoutedEventArgs e)
{
TicketPrice TP = new TicketPrice();
TP.ShowDialog();
}
in New Window form i have following code:
private void BtnSave_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("sometext");
}
on clicking messagebox button the form (TicketPrice) also is closing;
how to show messagebox without closing the form?
If i'd change TP.ShowDialog(); to TP.Show();, it works correctly. I have this problem only with this TP.ShowDialog();
xaml of button
<Button x:Name="BtnSave" HorizontalAlignment="Left" Margin="619,362,0,0" VerticalAlignment="Top" Width="165" Height="66" IsCancel="True" TabIndex="4" Click="BtnSave_Click">
<StackPanel Orientation="Horizontal">
<TextBlock Text="save " HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="SemiBold" />
<Image Source="pack://siteoforigin:,,,/Resources/Save.png" Height="50" Width="59" />
</StackPanel>
</Button>
You're seeing the IsCancel property on the Button working as advertised. Don't set it to true and clicking the button won't automatically close the dialog.
I want to pass an argument over to the previous page I visited when using a Binding GoBackCommand in the NavigationHelper.
The Back button in XAML
<Button x:Name="backButton"
Margin="39,59,39,0"
Command="{Binding NavigationHelper.GoBackCommand, ElementName=pageRoot}"
Style="{StaticResource NavigationBackButtonNormalStyle}"
VerticalAlignment="Top"
AutomationProperties.Name="Back"
AutomationProperties.AutomationId="BackButton"
AutomationProperties.ItemType="Navigation Button"
IsEnabled="{Binding IsBackEnabled}"/>
I want to pass the argument similar to when I trigger an EventHandler and navigate forward, e.g
C# Code Behind
Send the argument
private void Button_Click(object sender, RoutedEventArgs e)
{
string myArg = "Hello";
this.Frame.Navigate(typeof(AnotherPage), myArg);
}
And retrieve it
protected override void OnNavigatedTo(NavigationEventArgs e)
{
string myParam = e.Parameter.ToString();
}
Here is a solution although there is probably a better way to do this
C# Code Behind
In your Page with the GoBackCommand, declare a GoBack method:
private void GoBack()
{
string myArg = "Hello";
this.Frame.Navigate(typeof(AnotherPage), myArg);
}
Then in your Page constructor just set the GoBackCommand to your GoBack method:
public MyPage()
{
this.InitializeComponent();
this.navigationHelper = new NavigationHelper(this);
this.navigationHelper.LoadState += navigationHelper_LoadState;
this.navigationHelper.SaveState += navigationHelper_SaveState;
this.navigationHelper.GoBackCommand = new RelayCommand(GoBack);
}
You can use CommandParameter in your XAML to do that.
<Button x:Name="backButton"
Margin="39,59,39,0"
Command="{Binding NavigationHelper.GoBackCommand, ElementName=pageRoot}"
CommandParameter="This is my parameter"
Style="{StaticResource NavigationBackButtonNormalStyle}"
VerticalAlignment="Top"
AutomationProperties.Name="Back"
AutomationProperties.AutomationId="BackButton"
AutomationProperties.ItemType="Navigation Button"
IsEnabled="{Binding IsBackEnabled}"/>
I'm looking for help with an app I'm building. I've an xml file being read into an app. This XML is of the following structure:
`<Tabs>
<Tab>
<Search name="ListSearch" Title="SearchHeader">
<Label Name="lblSchema"></Label>
<ComboBox Name="comboxSchema" Visibility="Visible" IsEnabled="True" ItemSource="{Binding AvailableSchema}" SelectedValue="{Binding SelectedSchema}" />
<ComboBox Name="comboxList" Visibility="Visible" IsEnabled="True" ItemSource="{Binding AvailableList}" SelectedValue="{Binding SelectedList}" />
<Label Name="lblCriteria"></Label>
<ComboBox Name="comboxFields" Visibility="Visible" IsEnabled="True" ItemSource="{Binding AvailableFields}" SelectedValue="{Binding SelectedField}" />
<ComboBox Name="comboxOperator" Visibility="Visible" IsEnabled="True" ItemSource="{Binding Operations}" SelectedValue="{Binding SelectedOperator}" />
<TextBox Name="txtBoxInputValue" Visibility="Visible" IsEnabled="True" Text="{Binding InputValue}" />
<CustomControl type="DatePicker"></CustomControl>
<Button Name="btnAddQueryLine" Content="{Binding TextOnAddQueryButton}" Command="{Binding CamlAddQueryLine}" Action="Publish"></Button>
<Button Name="btnPasteQueryLine" Content="{Binding TextOnPasteQueryButton}" Command="{Binding CamlPasteQueryLine}" Action="Preview"></Button>
<Button Name="btnRemoveQueryLine" Content="{Binding TextOnRemoveQueryButton}" Command="{Binding CamlRemoveQueryLine}" Action="UnPublish"></Button>
<Button Name="btnClearQuery" Content="{Binding TextOnClearQueryButton}" Command="{Binding CamlClearQuery}" Action="UnPreview"></Button>
<Button Name="btnCamlSearch" Content="{Binding TextOnSearchQueryButton}" Command="{Binding CamlSearch}" Action="Meh"></Button>
<Button Name="btnCloseSearch" Content="{Binding TextOnCloseQueryButton}" Command="{Binding CloseSearch}" Action="NewMeh"></Button>
</Search>
</Tab>
</Tabs>`
So I read in the xml, and use methods like this to add buttons etc to the ribbon:
private void AddButtonToGroup(string header,RibbonGroup group,string command,string action)
{
RibbonButton button = new RibbonButton();
button.Label = header;
button.Name = action;
button.Click += new RoutedEventHandler(button_Click);
group.Items.Add(button);
}
with the following event handler:
void button_Click(object sender, RoutedEventArgs e)
{
Button clicked = (Button)sender;
MessageBox.Show("Button Clicked!");
MessageBox.Show("Performing Action:" + clicked.Name);
}.
The problem I have, is that this isn't the requirement- the event handler is hard coded. Is there any way to create event handlers dynamically? Can anyone point me in the right direction?
You could create a method that returns an Action<object, RoutedEventArgs>:
private Action<object, RoutedEventArgs> MakeButtonClickHandler()
{
return (object sender, RoutedEventArgs e) =>
{
// Put your code here, it will be called when
// the button is clicked
};
}
So MakeButtonClickHandler returns a new anonymous function each time it's called. Then assign it like this:
button.Click += new RoutedEventHandler(MakeButtonClickHandler());
Another way of accomplishing the same thing is to do this inline, like so:
button.Click += (object sender, RoutedEventArgs e) =>
{
// Put your code here
};
For some more information, take a look at Anonymous Functions on MSDN.
You need to define a set of actions that the user will be able to do. Then assign a name to each one of them and implement the actions in code.
For example, the XML would be:
<Button Content="TextOnAddQueryButton" Command="CamlAddQueryLine"></Button>
In code, you would assign the event handler like this:
private void AddButtonToGroup(string header,RibbonGroup group,string command,string action)
{
RibbonButton button = new RibbonButton();
button.Tag = command;
//...
}
And the handler for the button would be:
void button_Click(object sender, RoutedEventArgs e)
{
Button clicked = (Button)sender;
switch (clicked.Tag)
{
case "CamlAddQueryLine":
// Call action for CamlAddQueryLine
break;
}
}