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.
Related
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.
I have a very simple sample code, a TextBox and a Button. User inputs some text in textBox and click the Button. It should show a common MessageBox which contains the text he just input in the TextBox.
Problem: the MessageBox shows blank! After some trial and error I found out the reason. I set in .xaml the Focusable of Button as false. Why? Because I want to stop the blinking effect of button after it is clicked once.
So I have an idea. I bind the Focusable to a property in ViewModel and initialized in constructor (or in private field as initial value) of ViewModel as false. Then in the Button-Click event handler before showing MessageBox I set the property to true and then after executing MessageBox set it to false again. Problem: Unfortunately, it doesn't work! It seems the Focusable can only be set once in constructor or in private field as initial value.
Does someone know how to solve this problem? I want to keep the Focusable of the Button to false (to avoid the Button blinking) and I want to get the text from TextBox by clicking the Button. Following is the sample code and feel free to modify and show me the solution. Thank you in advance.
XAML / View
<Grid Width="300" Height="300">
<StackPanel VerticalAlignment="Center">
<TextBox Width="150" Text="{Binding Path=MyText}" />
<Button x:Name="ShowText"
Width="100"
Content="Show Text"
Focusable="{Binding Path=MyFocus}" />
</StackPanel>
</Grid>
View model
public class ShellViewModel : PropertyChangedBase
{
private String _myText;
public String MyText
{
get { return _myText; }
set
{
_myText = value;
NotifyOfPropertyChange(() => MyText);
}
}
private Boolean _myFocus = false; // if it is true, the MessageBox can show MyText, otherwise MessageBox shows blank
public Boolean MyFocus
{
get { return _myFocus; }
set
{
_myFocus = value;
NotifyOfPropertyChange(() => MyFocus);
}
}
public void ShowText()
{
//MyFocus = true; // this doesn't work
MessageBox.Show(MyText);
//MyFocus = false; // this doesn't work
}
}
<Grid Width="300" Height="300">
<StackPanel VerticalAlignment="Center">
<TextBox Width="150" Text="{Binding MyText, Mode=TwoWay}" />
<Button x:Name="ShowText"
Width="100"
Content="Show Text"
Focusable="{Binding MyFocus}" />
</StackPanel>
</Grid>
or
<Grid Width="300" Height="300">
<StackPanel VerticalAlignment="Center">
<TextBox Width="150" x:Name="MyText" />
<Button x:Name="ShowText"
Width="100"
Content="Show Text"
Focusable="{Binding MyFocus}" />
</StackPanel>
</Grid>
that should work either way, the way you did the binding wouldn't ever update the underlying property since it wasn't considered bi-directional. Therefore Mode=TwoWay was necessary on the 1st version, the second version uses CM's conventions to find the the textbox and bind it to a property of the same name on the viewmodel.
not sure what blinking your referring to the default style doesn't have a blink... at least not on windows 8.1 or windows 10. The only thing focusable does in the regard of the code frag you did was prevent keyboard access..
In a window got a lisbox which is bind to a list which is of type Employee having checkbox adjacent to each employee name and can be selected individually.
Got another control check box with "select all" option.
I'm able to do "select all" "select none" easily by binding the select all checkbox's isChecked to a property IsSelectAllChecked in my viewModel.
However if select all option is true and every employee items in lisbox is checked..
if one of item I uncheck how can I remove check from select all option checkbox.
<StackPanel Grid.Row="1">
<CheckBox Margin="20,15,0,15" IsChecked="{Binding Path=IsSelectAllChecked}">
<TextBlock VerticalAlignment="Center" Text="Select All" />
</CheckBox>
can anybody advise
The IsChecked of the checkboxes for the employees should also have a binding to an IsSelected property of the employee viewmodel. In the setter of that property you can evaluate if changes to IsSelectAllChecked are needed.
Here is how I would do it:
Here is your Select All Checkbox and the bound property:
<CheckBox Margin="20,15,0,15" Content="Select all"
IsChecked="{Binding Path=IsSelectAllChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
public bool IsSelectAllChecked
{
get
{
return isSelectAllChecked
}
set
{
isSelectAllChecked = value;
// Do some code here to turn all selected booleans to true
SelectAll();
OnPropertyChanged("IsSelectAllChecked"); // Fire OnPropertyChanged event, important for TwoWay Binding!!
}
Note that the Binding for your CheckBox is now in TwoWay mode, and with UpdateSourceTrigger=PropertyChanged . This will allow:
to change value of the bound property from the code ( TwoWay )
to update the CheckBox state when the value is updated ( UpdateSourceTrigger=PropertyChanged )
Up next: here is one of your checkboxes and the equivalent in code
<CheckBox Content="Select one"
IsChecked="{Binding Path=OneOfYourBools, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
public bool OneOfYourBools
{
get
{
return oneOfYourBools;
}
set
{
oneOfYourBools = value;
// If the isAllSelected was true, turn it to false!
if (this.IsSelectAllChecked)
{
this.IsSelectAllChecked = false;
}
OnPropertyChanged("OneOfYourBools"); // Fire OnPropertyChanged event, important for TwoWay Binding!!
}
And this should do the trick : when one bool is updated, the selectAll bool is updated as well, and vice versa
I have on checkbox inside telerik combo control. If User click on "All" option from checkbox list then I want select all checkboxs.
checkbox values.
My Sample code is below.
<telerik:RadComboBox Name="rcbDays" Grid.Row="1" Grid.Column="1" Width="200" HorizontalAlignment="Left" ItemsSource="{Binding MonthDaysList}" VerticalAlignment="Center" >
<telerik:RadComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Name="chkDays" Content="{Binding DaysText}"
Tag="{Binding DaysValue}" Checked="chkDays_Checked" />
</StackPanel>
</DataTemplate>
</telerik:RadComboBox.ItemTemplate>
</telerik:RadComboBox>
private void chkWeeks_Checked(object sender, RoutedEventArgs e)
{
//Here I want code for selecting all checkboxes.
}
The items that you bound the ComboBox to should have a property like IsSelected, then you should bind IsChecked of the data-template CheckBox to that. Then you just need to iterate over the source collection and set IsSelected=true on all items.
e.g.
public class MyClass : MyBaseClass // Whatever you may have called it,
{
public bool IsSelected { ... }
public string DaysText { ... }
//...
}
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsSelected}" Content="{Binding DaysText}" Tag="{Binding DaysValue}" />
</StackPanel>
</DataTemplate>
//In the handler that is supposed to select all
foreach (var item in MonthDaysList) item.IsSelected = true;
Of course the property needs to have change notifications.
(Also a note on usability: I do not thing that ComboBoxes should contain CheckBoxes, if you need multiple item selection use a ListBox)
You need to take one more property isSelected as said by H.B.
add IsChecked="{Binding IsSelected}" to CheckBox tag in xaml file. Create one property in the appropriate class i.e. public bool isSeleted.......
When you get in to event chkWeeks_Checked() in this function get reference of the ComboBox item source like objList = (TypeCastYourClassType)YourComboBox.ItemSource;... Now the objList contains all checkbox items. Iterate through objList collection and get isSeleted property for each and every single item and that's done....
In your case
MonthDayList = (TypeCastYourClassType)rcbDays.ItemSource;
for(int i=0;i<MonthDayList.Count;i++)
{
MonthDayList[i].isSelected = true;
}
Here is some good discussion for allowing multiple values to be selected in the telerik combobox.
It uses checkbox within combobox
http://codedotnets.blogspot.in/2012/02/checkboxes-in-comboxes-to-allow.html
Thanks :)
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