How to disable a button dynamically - wpf

I want to gray out a button dynamically. How to do that?

in xaml
<Button Name="myButton">Click Me</Button>
in code behind
myButton.IsEnabled = false;

Set its IsEnabled property to false. You can do this either in code-behind or with triggers/styles, depending on your needs there.

here id more sophisticated way (WPF way) is to bind Command to the Button.
<Button Name="button1" VerticalAlignment="Top" Width="94" Command="{Binding MyCommand}"
in ViewModel which is bound to the view's dataContext:
public ICommand MyCommand
{
get
{
return new DelegateCommand<string>(ExecuteSomething,IsExecutable);
}
}
here is ExecuteSomething the method which will be executed by clicking your button
IsExecutable - perdicate while it returns false the Button will be disable

Related

How to bind IsEnabled properties of a parent to a CheckBox of a child in WPF?

This works if CheckBox 'test1' is defined in the same page.
<Button IsEnabled="{Binding ElementName=test1, Path=IsChecked}" />
However, if I move CheckBox 'test1' to an UserControl and then try to bind it in such a way:
<Button IsEnabled="{Binding ElementName=userControlElementName, Path=test1.IsChecked}" />
I get no results when checking the 'test1' CheckBox.
What am I missing?
Edit
UserControl and Button are contained in the same View.
According to your explanation, it seems to me that you are doing something wrong, since such a task arose.
But if you do not go into the essence of the general task, then for the behavior you require, you should add a property to UserControl, to which you can bind both a child and an external element.
Your UserControl:
public partial class MyUC: UserControl
{
public bool ButtonIsEnabled {get; set;}
<Button IsEnabled="{Binding ButtonIsEnabled, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MyUC}}}"
Parent Page:
<local:MyUC x:Name="userControlElementName"/>
<Button IsEnabled="{Binding ButtonIsEnabled, ElementName=userControlElementName}"/>
P.S. If you need to change the value of ButtonIsEnabled from Sharp, then it should be declared as a DependencyProperty.

IsEnabled = false makes WPF button disappeared while using caliburn micro

I have a button in my WPF project, which looks like this:
<Button
Grid.Column="1"
HorizontalAlignment="Left"
x:Name="Add"
IsEnabled="False"
BorderThickness="0"
Grid.Row="1" VerticalAlignment="Top"
Height="23" Width="29" Margin="10,0,0,0">
<StackPanel>
<Image Source="\Resources\Pictures\Add.png"
Width="20" Height="20"/>
</StackPanel>
</Button>
In the corresponding ViewModel I have Add method and CanAdd property:
public bool CanAdd
{
get { return true; }
}
public void Add()
{
//some code
}
The problem is that when IsEnabled property is set to False, Button dissapears. I know that this is because of caliburn micro convetions. How can I modify this conventions, so that When I set IsEnabled to False button disables, and when CanAdd is false it becomes collapsed (as it is now)?
You shouldn't set IsEnabled to false in the XAML markup. The Button will be disabled when the CanAdd property returns false only. So if you want to disable the Button, you should implement your view model to return false from CanAdd. The view shouldn't decide when to enable the Button.
If you want to hide the Button you should either set its Visibility property to Hidden or Collapsed in the XAML, or bind it to either a Visibility source property of the view model or to a bool property and use a BoolToVisibilityConverter.
Disabling a Button doesn't hide it.
I defined IsEnabled property for this button in xaml for test purposes only. When The CanAdd is false in ViewModel, button dissapears automatically. To solve this I have to set Visibility property of the button in xaml to Visible and there is no need of additional properties (type of visibility) if you really don't want dissapear button in specific cases.

How can I identify which button was clicked using MVVM Pattern in WPF?

I am using MVVM Pattern. I have two buttons. on Click I need to identify which button was clicked. How I can bind buttons in XAMl so that I can identify which button was clicked.
If you really use MVVM then bind Command of each button to corresponding ICommand in your view-model. It will be two different commands so you don't need to do any special actions to distinguish one button from another.
XAML:
<Button Content="FirstButton"
Command="{Binding Path=FirstCommand, Mode=OneTime}"/>
<Button Content="SecondButton"
Command="{Binding Path=SecondCommand, Mode=OneTime}"/>
View-Model:
public sealed class ViewModel : INotifyPropertyChanged
{
// ...
public ICommand FirstCommand { get; }
public ICommand SecondCommand { get; }
// ...
}
If you want to use the same Command for multiple buttons, you can use CommandParameter.
<Button Content="buttonContent1" Command="{Binding ButtonClickCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Content}"/>
And in your command delegate method you can use something like this:
private void ButtonClickCommandHandler(object parameter)
{
switch(parameter.ToString())
{
case buttonContent1:
...
case buttonContent2:
...
}
}
Here button is identified by its content of course you can change it to some other property like Tag

Why isn't my Silverlight Datagrid Delete Button firing the event?

I have datagrid with a delete button XAML looks like:
<sdk:DataGridTemplateColumn Header="Del/Tgl" >
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Delete"
Command="{Binding DeleteRowCommand}"
CommandParameter="{Binding Column}"
/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
I implemented ICommand as DelegateCommand by copying the code from John Papa. I added a public property to my ViewModel :
public ICommand DeleteRowCommand {get;set;}
In the constructor of my viewModel I set the command:
this.DeleteRowCommand = new DelegateCommand(onDelete, CanDelete);
and finally defined the onDelete, and CanDelete:
private void onDelete(object param)
{
// Get the Column Name
string strColumnName = param as string ?? string.Empty;
}
private bool CanDelete(object param)
{
// If we ae here we can delete the row
return true;
}
Everything works on my Silvelight grid but the delete button click, and I never go to onDelete function. What am I doing wrong?
Basically Command binding will look for DeleteRowCommand property inside the Object ( I mean the list of object that is binded as ItemSource to the datagrid). So you need to set the Source of Binding or use relativesource if you are using SL5.
Cheers!
Vinod

WPF ListBox display last item differently

I want to have a listbox, that allows the user to fetch lets say 20 items from the DB and displays a hint on the last row of the listbox if there are more items to be fetched. When the user clicks on this last row, additional items should be retrieved from the DB, until there aren't any more and the last line displays this information.
First:
listitem1
listitem2
...
listitem19
listitem20
Button: <get_more>
after button press:
listitem1
listitem2
...
listitem39
listitem40
Info: <no more items>
Could all this be done in XAML only?
What would be the best solution to implement this?
Dude -- Everything can be done with XAML :D
Following a MVVM approach, I'd recommend you to do the following:
1/ Getting started: A DockPanel
<DockPanel LastChildFill="True">
<Button DockPanel.Dock="Bottom" />
<ListBox />
</DockPanel>
2/ Bind your ListBox to an ObservableCollection in your ViewModel:
<ListBox ItemsSource="{Binding ListElements}" />
In the ViewModel:
private ObservableCollection<String> _listElements;
public ObservableCollection<String> ListElements
{
get { return _listElements; }
set { _listElements = value; }
}
3/ Bind your Button's content to a predefined String:
<Button Content="{Binding ButtonString}" />
In the ViewModel:
public String ButtonString
{
get
{
//There, define if there are any more things to display
}
}
4/ Your Button fires a Command launching a method, let's say GetMore() :
<Button Content="{Binding ButtonString}" Command="{Binding GetMoreCommand} />
In ViewModel:
private void GetMore()
{
//append to the _listElements new elements from the list
//Update the ButtonString if there are no more elements
}
And there you go!
(you can also, if needed, define a button removing things from the ObservableCollection for example)

Resources