How to get CheckBox state changed for multiple checkboxes? - checkbox

I need to implement somethingh like this, if user will select one checkbox it will hide some component from UI, if user will select another checkbox it will hide some different components from UI. I have implemented this using onCheckedChanged Listner.
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
switch (buttonView.getId()){
case R.id.checkbox_regread:
if(isChecked){
btn_reg_rw.setText("Read");
cb_reg_write.setEnabled(false);
}else{
cb_reg_write.setEnabled(true);
}
break;
case R.id.checkbox_regwrite:
if(isChecked){
btn_reg_rw.setText("Write");
cb_reg_read.setEnabled(false);
}else{
cb_reg_read.setEnabled(true);
cb_reg_read.setChecked(false);
}
break;
}
But problem i am facing is that i getting the event for checkbox_rewrite but not able to get the event for R.id.checkbox_regread:. I have check with the Ids, they are correct.
give me any idea why this is happening?
Thanks,

Related

Is a Value changed through Input?

How do I know when is a value of any control changed by user input (interaction with mouse or keyboard)?
Any suggestions? Is there a common way for this?
EDIT:
I am seeking for attached property or extending already given controls or whatever is needed just to get notified whether user input is taking place at the time value is changed. eg ComboBox SelectedItem changed by user input (User could enter text or select an item in drop down menu)
Its pure View thing therefore I am sorry but no ViewModel solutions for this issue will be accepted.
The simplest way would simply be to register to the Binding.TargetUpdated event, which is fired when the UI-side is updated (while Binding.SourceUpdated is fired when the ViewModel-side is updated)
Use a property with backing field in your view model. Introduce a second setter - a SetProp() method - that you use inside your ViewModel. That way you can add different behavior, depending on the origin of the call.
```
private bool mMyProp;
public bool MyProp
{
get { return mMyProp; }
set
{
if (mMyProp != value)
{
mMyProp = value;
// Todo: add here code specific for calls coming from the UI
RaisePropertyChanged(() => MyProp);
}
}
}
public void SetPropFromViewModel(bool value)
{
if (mMyProp != value)
{
mMyProp = value;
// Todo: add here code specific for calls coming from ViewModel
RaisePropertyChanged(() => MyProp);
}
}

Windows Form Dropdown how to get previously selected value

I come from web background, now developing a windows application.
Application has drop down which shows the selected item (which comes from DB). I've a requirement that on selection of any other value than existing one perform xyz business logic.
I could use the index change event handler however, if they select other items and select back same I don't want to perform xyz business logic.
Therefore, can someone please help how it's possible to compare the selected value with one selected on load?
I could have session to store the previous state but not sure how can we do same in windows form.
In this case, your concept of session storage is a local storage variable. An example class:
public class MyForm : Form
{
private Int32 _selIdx = -1; //this is local to the Form and accessible anywhere within the MyForm class
public MyForm() { }
private void MyForm_Load(Object sender, EventArgs e)
{
//load database data, add to combo box, then capture the index
_selIdx = myComboBox.SelectedIndex;
}
//I prefer this method because it reacts to user interaction, and not programmatic change of index value
private void myComboBox_SelectionChangeCommitted(Object sender, EventArgs e)
{
//index changed, react
if (!_selIdx.Equals(myComboBox.SelectedIndex))
{
//not a match, do something...
}
}
}

Pattern for binding commands on a child ViewModel from a parent menu

I'm creating a WPF MVVM app using Caliburn Micro. I have a set of buttons in a menu (Ribbon) that live in the view for my shell view model, which is a ScreenConductor. Based on the currently active Screen view model, I would like to have the ribbon buttons be disabled/enabled if they are available for use with the active Screen, and call actions or commands on the active Screen.
This seems like a common scenario. Is there a pattern for creating this behavior?
Why don't you do the reverse thing, instead of checking which commands are supported by the current active screen, let the active screen populate the menu or ribbon tab with all the controls that it supports, (i would let it inject its own user control which might just be a complete menu or a ribbon tab all by itself), this will also enhance the user experience as it will only show the user the controls that he can work with for the current active screen.
EDIT: Just looking at your question again and I'm thinking that this is much simpler than it looks
The only issue I can see you having is that a lack of a handler (and guard) method on a child VM will mean that buttons that don't have an implementation on the currently active VM will still be enabled.
The default strategy for CM is to try and find a matching method name (after parsing the action text) and if one is not found, to leave the button alone. If you were to customise that behaviour so that the default is for buttons to be disabled, you could easily get it working by just implementing the command buttons in your shell, making sure to set the command target to the active item:
In the shell define your buttons, making sure they have a target that points to the active child VM
<Button cal:Message.Attach="Command1" cal:Action.TargetWithoutContext="{Binding ActiveItem}" />
Then just implement the method in your child VM as per usual
public void Command1() { }
and optionally a CanXX guard
public bool CanCommand1
{
get
{
if(someCondition) return false;
return true;
}
}
Assuming you don't get much more complex than this, it should work for you
I'm going to have a quick look at the CM source and see if I can come up with something that works for this
EDIT:
Ok you can customise the ActionMessage.ApplyAvailabilityEffect func to get the effect you want - in your bootstrapper.Configure() method (or somewhere at startup) use:
ActionMessage.ApplyAvailabilityEffect = context =>
{
var source = context.Source;
if (ConventionManager.HasBinding(source, UIElement.IsEnabledProperty))
{
return source.IsEnabled;
}
if (context.CanExecute != null)
{
source.IsEnabled = context.CanExecute();
}
// Added these 3 lines to get the effect you want
else if (context.Target == null)
{
source.IsEnabled = false;
}
// EDIT: Bugfix - need this to ensure the button is activated if it has a target but no guard
else
{
source.IsEnabled = true;
}
return source.IsEnabled;
};
This seems to work for me - there is no target for methods which couldn't be bound to a command, so in that case I just set IsEnabled to false. This activates buttons only when a method with a matching signature is found on the active child VM - obviously give it a good test before you use it :)
Create methods and accompanying boolean properties for each of your commands on your shell view model. (See code below for an example.) Caliburn.Micro's conventions will wire them up to the buttons for you automatically. Then simply raise property changed events for the boolean properties when you change views to have them be re-evaluated.
For example, let's say you have a Save button. The name of that button in your xaml would be Save, and in your view model, you would have a Save method along with a CanSave boolean property. See below:
public void Save()
{
var viewModelWithSave = ActiveItem as ISave;
if (viewModelWithSave != null) viewModelWithSave.Save();
}
public bool CanSave { get { return ActivateItem is ISave; } }
Then, in your conductor, whenever you change your active screen, you would call NotifyOfPropertyChange(() => CanSave);. Doing this will cause your button to be disabled or enabled depending upon if the active screen is capable of dealing with that command. In this example, if the active screen doesn't implement ISave, then the Save button would be disabled.
I would use the Caliburn.Micro event aggregation in this scenario, as follows:
Create a class named ScreenCapabilities with a bunch of Boolean attributes (e.g. CanSave, CanLoad, etc.)
Create a message named ScreenActivatedMessage with a property of type ScreenCapabilities
Create a view model for your ribbon that subscribes to (handles) the ScreenActivatedMessage
In the ribbon view model's Handle method, set the local CanXXX properties based on the supplied ScreenCapabilities.
It would look something like this (code typed by hand, not tested):
public class ScreenCapabilities
{
public bool CanSave { get; set; }
// ...
}
public class ScreenActivatedMessage
{
public ScreenCapabilities ScreenCapabilities { get; set; }
// ...
}
public class RibbonViewModel : PropertyChangedBase, IHandle<ScreenActivatedMessage>
{
private bool _canSave;
public bool CanSave
{
get { return _canSave; }
set { _canSave = value; NotifyPropertyChanged(() => CanSave); }
}
// ...
public void Handle(ScreenActivatedMessage message)
{
CanSave = message.ScreenCapabilities.CanSave;
// ...
}
}
Then, somewhere appropriate, when the screen changes, publish the message. See see Caliburn.Micro wiki for more info.
Define a property (let's say ActiveScreen) for the active screen in the shell view model.
And let's assume you have properties for the each button such as DeleteButton, AddButton.
Screen is a viewmodel for the screens.
private Screen activeScreen;
public Screen ActiveScreen
{
get
{
return activeScreen;
}
set
{
activeScreen= value;
if (activeScreen.Name.equals("Screen1"))
{
this.AddButton.IsEnabled = true;
this.DeleteButton.IsEnabled = false;
}
if else (activeScreen.Name.equals("Screen2"))
{
this.AddButton.IsEnabled = true;
this.DeleteButton.IsEnabled = true;
}
NotifyPropertyChanged("ActiveScreen");
}
}

zk: form combobox is not empty on an event to add new object

I am using zk frameworks mvvm approach to add, edit an object. When I click add button first time, the opening form is empty and it runs smoothly. After editing a record from a list, i am getting combo-box values preselected and the already selected value must not be selected, otherwise, i get null and i can't submit the form. It's mean that I can't choose selected value again for successful crud operation. My edit function for every case are working fine and there is no issue and all textbox and intbox are working normally
i am following this article
http://books.zkoss.org/wiki/Small_Talks/2012/February/MVVM_in_ZK6:_Form_Binding
i have three objects, newObject, selectedObject and editObject
my form snippet from zul file
<grid sizedByContent="true"
form="#id('ds')
#load(vmc.newObject, after='addInvoke') #save(vmc.newObject, before='add')
#load(vmc.editObject, after='editInvoke') #save(vmc.editObject, before='edit')
#validator('com.example.MyValidator')"
>
<combobox model="#load(ds.unitList)"
selectedItem="#bind(ds.abc.unit)" readonly="true" maxlength="50"/>
my method snippet for edit and add functions from SampleViewModel is as follows
#Command("edit")
#NotifyChange({ "objectList", "selectedObject", "editObject" })
#Override
public void edit() {
service.editKpi(editObject);
editObject = null;
}
#Command("addInvoke")
#NotifyChange("newObject")
#Override
public void onClickAddButton(){
enableEditMode(false);
isNewMode = true;
newObject = new AbcDTO();
}
i have fixed it my self.
solution is use value in combo-box too along with selecteditem

WPF ComboBox SelectedItem - change to previous value

I have a ComboBox that has the SelectedItem bound to the ViewModel.
<ComboBox SelectedItem="{Binding SelItem, Mode=TwoWay}" ItemsSource="{Binding MyItems}">
When the user selects a new Item in the View ComboBox, I want to display a prompt and verify that they want to make the change.
In the SetItem Property setter in the View Model, I display a Dialog to confirm the selection. When they say yes, it works fine.
My problem is, when the user clicks on "No" I am not sure who to get the ComboBox
to revert back to the previous value. The Property in the ViewModel has the correct
older value, however in the View the ComboBox displays the newly Selected Value.
I want the user to select an item, confirm they want to go ahead with it, and if they
decide not to, I want the ComboBox to revert back to the previous item.
How can I accomplish this?
Thanks!
When the user says "no", WPF is unaware that the value has changed. As far as WPF is concerned, the value is whatever the user selected.
You might try raising a property changed notification:
public object SelItem
{
get { ... }
set
{
if (!CancelChange())
{
this.selItem = value;
}
OnPropertyChanged("SelItem");
}
}
The problem is, the change notification happens within the same context of the selection event. Thus, WPF ignores it because it already knows the property has changed - to the item the user selected!
What you need to do is raise the notification event in a separate message:
public object SelItem
{
get { ... }
set
{
if (CancelChange())
{
Dispatcher.BeginInvoke((ThreadStart)delegate
{
OnPropertyChanged("SelItem");
});
return;
}
this.selItem = value;
OnPropertyChanged("SelItem");
}
}
WPF will then process this message after it's done processing the selection changed event and will therefore revert the value in the view back to what it should be.
Your VM will obviously need access to the current Dispatcher. See my blog post on a base VM class if you need some pointers on how to do this.
Thanks for this question and answers. The Dispatcher.BeginInvoke helped me and was part of my final solution, but the above solution didn't quite work in my WPF 4 app.
I put together a small sample to figure out why. I had to add code that actually changed the underlying member variable's value temporarily so that when WPF re-queried the getter, it would see that the value chaned. Otherwise, the UI didn't properly reflect the cancellation and the BeginInvoke() call did not do anything.
Here's a my blog post with my sample showing a non-working and a working implementation.
My setter ended up looking like this:
private Person _CurrentPersonCancellable;
public Person CurrentPersonCancellable
{
get
{
Debug.WriteLine("Getting CurrentPersonCancellable.");
return _CurrentPersonCancellable;
}
set
{
// Store the current value so that we can
// change it back if needed.
var origValue = _CurrentPersonCancellable;
// If the value hasn't changed, don't do anything.
if (value == _CurrentPersonCancellable)
return;
// Note that we actually change the value for now.
// This is necessary because WPF seems to query the
// value after the change. The combo box
// likes to know that the value did change.
_CurrentPersonCancellable = value;
if (
MessageBox.Show(
"Allow change of selected item?",
"Continue",
MessageBoxButton.YesNo
) != MessageBoxResult.Yes
)
{
Debug.WriteLine("Selection Cancelled.");
// change the value back, but do so after the
// UI has finished it's current context operation.
Application.Current.Dispatcher.BeginInvoke(
new Action(() =>
{
Debug.WriteLine(
"Dispatcher BeginInvoke " +
"Setting CurrentPersonCancellable."
);
// Do this against the underlying value so
// that we don't invoke the cancellation question again.
_CurrentPersonCancellable = origValue;
OnPropertyChanged("CurrentPersonCancellable");
}),
DispatcherPriority.ContextIdle,
null
);
// Exit early.
return;
}
// Normal path. Selection applied.
// Raise PropertyChanged on the field.
Debug.WriteLine("Selection applied.");
OnPropertyChanged("CurrentPersonCancellable");
}
}
Another way to do it (make sure you also read the comments):
http://amazedsaint.blogspot.com/2008/06/wpf-combo-box-cancelling-selection.html
From the link:
Another solution for issue of recursive calling of event handler without global variable is to cancel handler assignment before programmatic selection change, and reassign it after that.
Ex:
cmb.SelectionChanged -= ComboBox_SelectionChanged;
cmb.SelectedValue = oldSel.Key;
cmb.SelectionChanged += ComboBox_SelectionChanged;
My way of doing it is to let the change go through and perform validation in a lambda that is BeginInvoked in the Dispatcher.
public ObservableCollection<string> Items { get; set; }
private string _selectedItem;
private string _oldSelectedItem;
public string SelectedItem
{
get { return _selectedItem; }
set {
_oldSelectedItem = _selectedItem;
_selectedItem = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("SelectedItem"));
}
Dispatcher.BeginInvoke(new Action(Validate));
}
}
private void Validate()
{
if (SelectedItem == "Item 5")
{
if (MessageBox.Show("Keep 5?", "Title", MessageBoxButton.YesNo) == MessageBoxResult.No)
{
SelectedItem = _oldSelectedItem;
}
}
}
or in your ViewModel:
Synchronization.Current.Post(new SendOrPostCallback(Validate), null);

Resources