RaiseCanExecuteChanged more convenience - command

I'd like to RaiseCanExecuteChanged when CanExecute condition got changed.
E.g.:
public class ViewModel
{
public viewModel()
{
Command = new RelayCommand(action,condition);
}
private bool condition()
{
return this.Condition1&&this.Condition2&&this.Condition3;
}
public bool Condition1
{
get{...}
set{.... **command.RaiseCanExecuteChanged();}**
}
public bool Condition2
{
get{...}
set{.... command.**RaiseCanExecuteChanged();}**
}
public bool Condition3
{
get{...}
set{.... **command.RaiseCanExecuteChanged();}**
}
}
That works fine.
But I don't like to write so many RaiseCanExecuteChanged, I want to set these changes automatically.
E.g
In RelayCommand, create a new method named RaiseChanged
public void RaiseChanged(XXXXXX XXX, params string[] propertyNames)
{
// for each property in propertyNames,
// RaiseCanExecuteChanged();
}
I put ViewModel vm as the parameters, and use vm.PropertyChanged+=(s,e)=>{}
But I don't think it's a good way to do this.
Does anyone have other ideas?

I develop my solution where I can do like that:
C# View Model:
public bool CanExecuteMethod(object sender)
{
}
public void ButtonExecuteMethod(object sender)
{
}
public event Action EventNotifyCanExecuteChanged;
private Action _DelegateNotifyCanExecuteChanged;
public Action DelegateNotifyCanExecuteChanged
{
get { return _DelegateNotifyCanExecuteChanged; }
set { _DelegateNotifyCanExecuteChanged = value; }
}
public void CanExecuteFlag
{
if (EventNotifyCanExecuteChanged != null) { EventNotifyCanExecuteChanged(); }
if (_DelegateNotifyCanExecuteChanged != null) { _DelegateNotifyCanExecuteChanged();}
}
XAML:
< Button Content="Button Cmd-ExCeCh" HorizontalAlignment="Left" Margin="27,231,0,0"
VerticalAlignment="Top" Width="120"
Command="{mark:BindCommandResource MainWindowViewModel,
ExecuteMethodName=ButtonExecuteMethod,
CanExecuteMethodName=CanExecuteMethod,
EventToInvokeCanExecuteChanged=EventNotifyCanExecuteChanged,
PropertyActionCanExecuteChanged=DelegateNotifyCanExecuteChanged}" />
I put/share this solution in my open source project MVVM-WPF XAML Mark-up Binding Extensions - http://wpfmvvmbindingext.codeplex.com

Related

AAC: How return result (handle click) from ViewModel to activity?

I want to use in my project Android Architecture Components (AAC).
Nice.
Here my activity:
import androidx.appcompat.app.AppCompatActivity;
public class TradersActivity extends AppCompatActivity {
private TradersViewModel tradersViewModel;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tradersViewModel = ViewModelProviders.of(this).get(TradersViewModel.class);
tradersViewModel.getIsEnableSwipeProgress().observe(this, new Observer<Boolean>() {
#Override
public void onChanged(Boolean isEnable) {
// do some work with UI
}
});
}
// button click
public void onClickViewJson(Trader trader) {
tradersViewModel.doClickJsonView(trader);
}
}
Here my ViewModel
public class TradersViewModel extends ViewModel {
private MutableLiveData<Boolean> isEnableSwipeProgress = new MutableLiveData<>();
public void doClickJsonView(Trader trader) {
// DO_SOME_COMPLEX_BUSINESS_LOGIC
}
public MutableLiveData<Boolean> getIsEnableSwipeProgress() {
return isEnableSwipeProgress;
}
}
In the screen I has button. And when click this button I call activity's method - onClickViewJson(Trader trader) .
This method call tradersViewModel.doClickJsonView(trader);
In the viewModel this method do some complex business logic.
After method finish it work I need to return result (json) to the my activity.
How I can do this?
Remember that in MVVM, ViewModels have not idea about your view.
Your ViewModel should expose variables so your views can observe and react over them.
private MutableLiveData<Boolean> isEnableSwipeProgress = new MutableLiveData<>();
private MutableLiveData<JSONDto> jsonLiveData = new MutableLiveData<>();
public void doClickJsonView(Trader trader) {
// DO_SOME_COMPLEX_BUSINESS_LOGIC
jsonLiveData.postValue(/* the json you obtain after your logic finish */ )
}
public MutableLiveData<Boolean> getIsEnableSwipeProgress() {
return isEnableSwipeProgress;
}
public LiveData<JSONDto> getJsonDto() {
return this.jsonLiveData;
}
And in your view, you react over your jsonDto changes:
tradersViewModel.getJsonDto().observe(this, new Observer<JSONDto>() {
#Override
public void onChanged(JSONDto json) {
if (json != null) {
// Do what you need here.
}
}
});

How to change a radio box from true to false using MVVM

So I have a radio button that I want to change from being unchecked to being checked based on if a button is clicked. So
the XAML code I have is:
<RadioButton GroupName="rdoExchange" Grid.Row="2" Grid.Column="0" x:Name="PauseRadioButton" Command="{Binding PauseCommand}" IsChecked="{Binding Path=check, Mode=TwoWay}" Margin="3"/>
And the View Model Code:
public string check = "True";
public void Reset(object obj)
{
check = "True";
}
private ICommand m_PauseCommand;
public ICommand PauseCommand
{
get
{
return m_PauseCommand;
}
set
{
m_PauseCommand = value;
}
}
private ICommand m_ResetCommand;
public ICommand ResetCommand
{
get
{
return m_ResetCommand;
}
set
{
m_ResetCommand = value;
}
}
private void SetProperty<T>(ref T field, T value, [CallerMemberName] string name = "")
{
if (!EqualityComparer<T>.Default.Equals(field, value))
{
field = value;
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
}
I've left out the relaycommand code and several other parts that I feel would be irrelevant to solving the problem.
Would something like this work?
XAML:
<RadioButton GroupName="rdoExchange" IsChecked="{Binding Path=OptionOneChecked, Mode=TwoWay}"/>
<Button Command="{Binding ToggleOptionOne}" Height="20" />
View Model:
public class ViewModel: NotificationObject
{
private bool _optionOneChecked;
public bool OptionOneChecked
{
get { return _optionOneChecked; }
set
{
if (value.Equals(_optionOneChecked)) return;
_optionOneChecked = value;
RaisePropertyChanged("OptionOneChecked");
}
}
public ICommand ToggleOptionOne
{
get { return new DelegateCommand(() => OptionOneChecked = !OptionOneChecked); }
}
}
using the NotificationObject class from the PRISM NuGet package.

Error in Binding Custom Textbox Property

I have created custom Textbox in Silverlight 4, MVVM and PRISM 4. The custom text box has dynamic behavior link it dynamically set TextMode to either Password or Text.
This is working perfect. ( if i am bind TextMode static)
<control:PasswordTextBox x:Name="customTextBox2" Width="100" Height="30" Grid.Row="4" Grid.Column="1" Text="{Binding Email}" TextMode="Password"/>
This is giving me an error (if i am binding with dynamic)
<control:PasswordTextBox x:Name="customTextBox1" Width="100" Height="30" Grid.Row="4" Grid.Column="1" Text="{Binding Email}" TextMode="{Binding WritingMode}"/>
following is my ViewModel code
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class UserRightsViewModel : NotificationObject, IRegionMemberLifetime
{
private Mode _writingMode = Mode.Text;
public Mode WritingMode
{
get { return _writingMode; }
set
{
_writingMode = value; RaisePropertyChanged("WritingMode");
}
}
[ImportingConstructor]
public UserRightsViewModel(IEventAggregator eventAggregator, IRegionManager regionManager)
{
UserSecurity security = new UserSecurity();
FormSecurity formSecurity = security.GetSecurityList("Admin");
formSecurity.WritingMode = Mode.Password;
}
}
following is the enum
namespace QSys.Library.Enums
{
public enum Mode
{
Text,
Password
}
}
following code for Custom PasswordTextBox
namespace QSys.Library.Controls
{
public partial class PasswordTextBox : TextBox
{
#region Variables
private string _Text = string.Empty;
private string _PasswordChar = "*";
private Mode _TextMode = Mode.Text;
#endregion
#region Properties
/// <summary>
/// The text associated with the control.
/// </summary>
public new string Text
{
get { return _Text; }
set
{
_Text = value;
DisplayMaskedCharacters();
}
}
/// <summary>
/// Indicates the character to display for password input.
/// </summary>
public string PasswordChar
{
get { return _PasswordChar; }
set { _PasswordChar = value; }
}
/// <summary>
/// Indicates the input text mode to display for either text or password.
/// </summary>
public Mode TextMode
{
get { return _TextMode; }
set { _TextMode = value; }
}
#endregion
#region Constructors
public PasswordTextBox()
{
this.TextChanged += new TextChangedEventHandler(PasswordTextBox_TextChanged);
this.KeyDown += new System.Windows.Input.KeyEventHandler(PasswordTextBox_KeyDown);
this.Loaded += new RoutedEventHandler(PasswordTextBox_Loaded);
}
#endregion
#region Event Handlers
void PasswordTextBox_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
//this.TextChanged += ImmediateTextBox_TextChanged;
}
public void PasswordTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (base.Text.Length >= _Text.Length) _Text += base.Text.Substring(_Text.Length);
DisplayMaskedCharacters();
}
public void PasswordTextBox_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
int cursorPosition = this.SelectionStart;
int selectionLength = this.SelectionLength;
// Handle Delete and Backspace Keys Appropriately
if (e.Key == System.Windows.Input.Key.Back || e.Key == System.Windows.Input.Key.Delete)
{
if (cursorPosition < _Text.Length)
_Text = _Text.Remove(cursorPosition, (selectionLength > 0 ? selectionLength : 1));
}
base.Text = _Text;
this.Select((cursorPosition > _Text.Length ? _Text.Length : cursorPosition), 0);
DisplayMaskedCharacters();
}
#endregion
#region Private Methods
private void DisplayMaskedCharacters()
{
int cursorPosition = this.SelectionStart;
// This changes the Text property of the base TextBox class to display all Asterisks in the control
base.Text = new string(_PasswordChar.ToCharArray()[0], _Text.Length);
this.Select((cursorPosition > _Text.Length ? _Text.Length : cursorPosition), 0);
}
#endregion
#region Public Methods
#endregion
}
}
I am getting following error if i am binding with dynamically.
Set property 'QSys.Library.Controls.PasswordTextBox.TextMode' threw an exception. [Line: 40 Position: 144]
Your answer would be appreciated.
Thanks in advance.
Imdadhusen
Try to change in your PasswordTextBox class
public Mode TextMode
{
get { return _TextMode; }
set { _TextMode = value; }
}
to
public static readonly DependencyProperty TextModeProperty =
DependencyProperty.Register("TextMode", typeof(Mode), typeof(PasswordTextBox), new PropertyMetadata(default(Mode)));
public Mode TextMode
{
get { return (Mode) GetValue(TextModeProperty); }
set { SetValue(TextModeProperty, value); }
}
You can read more here:
Dependency Properties Overview
DependencyProperty Class
The main paragraph from the second link is:
A DependencyProperty supports the following capabilities in Windows
Presentation Foundation (WPF):
....
The property can be set through data binding. For more information about data binding dependency properties, see How to: Bind the
Properties of Two Controls.
I provide links for WPF, but basically for Silverlight it's the same

Create custom control with nested tag like GridView >> Columns >> Paging

Expert,
I would like to create a custom control with following feature and this is successfully created:
<fv:Album Runat="Server" Id="WeddingAlbum" Width="600" Height="600" SkinColor="SkyBlue" AllowedFileExtensions="jpg|png|jpeg|gif" MessageDelay="6000"
SavePageUrl="saveupload.aspx" RemovePageUrl="removeupload.aspx"
ThumbnailHeight="150" Thumbnailwidth="150" ThumbnailFadeIn="slow" ThumbnailFadeOut="slow" ThumbnailShowDelete="true"
PopupView="true" PopupViewType="All" PopupOverlayShow="true" PopupTransitionIn="elastic" PopupTransitionOut="elastic"
</fv:Album>
but i would like to segregate Album with Thumbnail and Popup tag. it look like
<fv:Album Runat="Server" Id="WeddingAlbum" Width="600" Height="600" SkinColor="SkyBlue" AllowedFileExtensions="jpg|png|jpeg|gif" MessageDelay="6000" SavePageUrl="saveupload.aspx" RemovePageUrl="removeupload.aspx">
<fv:Thumbnail Height="150" width="150" FadeIn="slow" FadeOut="slow" ShowDelete="true" />
<fv:Popup View="true" ViewType="All" OverlayShow="true" TransitionIn="elastic" TransitionOut="elastic"/>
</fv:Album>
can any body tell me how can i achieve the above functionality?
Example:
<asp:GridView ID="productGridView" Runat="server" DataSourceID="productsDataSource"
<FooterStyle ForeColor="#8C4510" BackColor="#F7DFB5"></FooterStyle>
<PagerStyle ForeColor="#8C4510" HorizontalAlign="Center"></PagerStyle>
<HeaderStyle ForeColor="White" BackColor="#A55129"></HeaderStyle>
</asp:GridView>
Thanks in advance!
Imdadhusen
Album.cs
namespace Imdadhusen.Controls.Web
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:Album runat=\"server\" />")]
[ToolboxBitmap(typeof(Album), "Album.bmp")]
public class Album : WebControl, IScriptControl
{
#region "Popup Properties"
private Popup _popup = new Popup();
//PersistenceMode.InnerProperty: Specifies that the property persists in
//the ASP.NET server control as a nested tag.
//DesignerSerializationVisibility.Content: Specifies that a visual
//designer serializes the contents of this property instead of the
//property itself.
[DefaultValue("")]
[Category("Custom")]
[PersistenceMode(PersistenceMode.InnerProperty)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Popup Popup
{
get { return _popup; }
set { _popup = value; }
}
#endregion
#region "Popup Properties"
private Thumbnail _thumbnail = new Thumbnail();
[DefaultValue("")]
[Category("Custom")]
[PersistenceMode(PersistenceMode.InnerProperty)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Thumbnail Thumbnail
{
get { return _thumbnail; }
set { _thumbnail = value; }
}
#endregion
#region "Control Properties"
public string UploadButtonID
{
get { return this.ViewState["UploadButtonID"] == null ? string.Empty : (string)this.ViewState["UploadButtonID"]; }
set { this.ViewState["UploadButtonID"] = value; }
}
/// <summary>
/// Location of the server-side upload script
/// </summary>
public string Action
{
get { return this.ViewState["Action"] == null ? string.Empty : (string)this.ViewState["Action"]; }
set { this.ViewState["Action"] = value; }
}
/// <summary>
/// Additional data to send
/// </summary>
public string ExtraData
{
get { return this.ViewState["ExtraData"] == null ? string.Empty : (string)this.ViewState["ExtraData"]; }
set { this.ViewState["ExtraData"] = value; }
}
/// <summary>
/// Callback to fire before file is uploaded
/// You can return false to cancel upload
/// </summary>
public string OnSubmitFunction
{
get { return this.ViewState["OnSubmitFunction"] == null ? string.Empty : (string)this.ViewState["OnSubmitFunction"]; }
set { this.ViewState["OnSubmitFunction"] = value; }
}
/// <summary>
/// Submit file as soon as it's selected
/// </summary>
public bool AutoSubmit
{
get { return this.ViewState["AutoSubmit"] == null ? true : (bool)this.ViewState["AutoSubmit"]; }
set { this.ViewState["AutoSubmit"] = value; }
}
/// <summary>
/// The type of data that you're expecting back from the server.
/// Html and xml are detected automatically.
/// Only useful when you are using json data as a response.
/// Set to "json" in that case.
/// </summary>
public string ResponseType
{
get { return this.ViewState["ResponseType"] == null ? string.Empty : (string)this.ViewState["ResponseType"]; }
set { this.ViewState["ResponseType"] = value; }
}
// When user selects a file, useful with autoSubmit disabled
public string OnChangeFunction
{
get { return this.ViewState["OnChangeFunction"] == null ? string.Empty : (string)this.ViewState["OnChangeFunction"]; }
set { this.ViewState["OnChangeFunction"] = value; }
}
/// <summary>
/// Fired when file upload is completed
/// WARNING! DO NOT USE "FALSE" STRING AS A RESPONSE!
/// </summary>
public string OnCompleteFunction
{
get { return this.ViewState["OnCompleteFunction"] == null ? string.Empty : (string)this.ViewState["OnCompleteFunction"]; }
set { this.ViewState["OnCompleteFunction"] = value; }
}
#endregion
#region "Page Events"
protected override void OnPreRender(EventArgs e)
{
if (!this.DesignMode)
{
//test for the existence of a ScriptManager
ScriptManager sMgr = ScriptManager.GetCurrent(Page);
if (sMgr == null)
throw new HttpException(
"A ScriptManager control must exist on the page.");
sMgr.RegisterScriptControl(this);
}
base.OnPreRender(e);
}
protected override void Render(HtmlTextWriter output)
{
Control btnUpload = this.NamingContainer.FindControl(this.UploadButtonID);
if (btnUpload == null) throw new HttpException("A UploadButtonID must point to an existing control on the page.");
StringBuilder startupscript = new StringBuilder();
startupscript.AppendLine("$().ready(function () {");
startupscript.AppendLine(" $(function () {");
startupscript.AppendFormat(" var btnUpload = $('#{0}');\n", btnUpload.ClientID);
startupscript.AppendLine(" new AjaxUpload(btnUpload, {");
startupscript.AppendFormat(" name: '{0}'", this.UniqueID);
if (!string.IsNullOrEmpty(this.OnChangeFunction))
startupscript.AppendFormat(",\n onChange: {0}", this.OnChangeFunction);
if (this.AutoSubmit)
{
startupscript.AppendFormat(",\n action: '{0}'", this.Action);
if (!string.IsNullOrEmpty(this.ResponseType))
startupscript.AppendFormat(",\n responseType: {0}", this.ResponseType);
if (!string.IsNullOrEmpty(this.OnSubmitFunction))
startupscript.AppendFormat(",\n onSubmit: {0}", this.OnSubmitFunction);
if (!string.IsNullOrEmpty(this.OnCompleteFunction))
startupscript.AppendFormat(",\n onComplete: {0}", this.OnCompleteFunction);
}
else
{
startupscript.Append(",\n autoSubmit: false");
}
startupscript.AppendLine("\n });");
startupscript.AppendLine(" });");
startupscript.AppendLine("});");
this.Page.ClientScript.RegisterStartupScript(this.GetType(), "startupscript", startupscript.ToString(), true);
base.Render(output);
}
#endregion
#region "IScriptControl Members"
IEnumerable<ScriptDescriptor> IScriptControl.GetScriptDescriptors()
{
return new ScriptDescriptor[] { };
}
IEnumerable<ScriptReference> IScriptControl.GetScriptReferences()
{
ScriptReference reference = new ScriptReference();
reference.Assembly = "PhotoAlbum";
reference.Name = "Imdadhusen.Controls.Web.Script.ajaxupload.3.5.js";
return new ScriptReference[] { reference };
}
#endregion
}
}
Popup.cs
namespace Imdadhusen.Controls.Web
{
/// <summary>
///ExpandableObjectConverter: Provides a type converter to convert expandable
///objects. It adds support for properties on an object to the methods and
///properties that TypeConverter provides.
/// </summary>
[TypeConverter(typeof(ExpandableObjectConverter))]
public class Popup
{
//View="true" ViewType="All" OverlayShow="true" TransitionIn="elastic" TransitionOut="elastic"
public Popup()
{
}
//start View
private bool _view;
[DefaultValue(true)]
[NotifyParentProperty(true)]
[RefreshProperties(RefreshProperties.Repaint)]
public bool View
{
get { return _view; }
set { _view = value; }
}
//end View
//start ViewType
private _ViewType _viewtype;
public enum _ViewType
{
All,
Single
}
[DefaultValue(_ViewType.All)]
[NotifyParentProperty(true)]
[RefreshProperties(RefreshProperties.Repaint)]
public _ViewType ViewType
{
get { return _viewtype; }
set { _viewtype = value; }
}
//end ViewType
//start ShowOverlay
private bool _overlayshow;
[DefaultValue(true)]
[NotifyParentProperty(true)]
[RefreshProperties(RefreshProperties.Repaint)]
public bool ShowOverlay
{
get { return _overlayshow; }
set { _overlayshow = value; }
}
//end ShowOverlay
//start TransitionIn
private _TransitionIn _transitionin;
public enum _TransitionIn
{
Elastic,
Fade,
None
}
[DefaultValue("")]
[NotifyParentProperty(true)]
[RefreshProperties(RefreshProperties.Repaint)]
public _TransitionIn TransitionIn
{
get { return _transitionin; }
set { _transitionin = value; }
}
//end TransitionIn
//start TransitionOut
private _TransitionOut _transitionout;
public enum _TransitionOut
{
Elastic,
Fade,
None
}
[DefaultValue(_TransitionOut.Elastic)]
[NotifyParentProperty(true)]
[RefreshProperties(RefreshProperties.Repaint)]
public _TransitionOut TransitionOut
{
get { return _transitionout; }
set { _transitionout = value; }
}
//end TransitionOut
}
}
Thumbnail.cs
namespace Imdadhusen.Controls.Web
{
/// <summary>
///ExpandableObjectConverter: Provides a type converter to convert expandable
///objects. It adds support for properties on an object to the methods and
///properties that TypeConverter provides.
/// </summary>
[TypeConverter(typeof(ExpandableObjectConverter))]
public class Thumbnail
{
//<fv:Thumbnail Height="150" width="150" FadeIn="slow" FadeOut="slow" ShowDelete="true" />
public Thumbnail()
{
}
//start Height
private int _height;
[DefaultValue(150)]
[NotifyParentProperty(true)]
[RefreshProperties(RefreshProperties.Repaint)]
public int Height
{
get { return _height; }
set { _height = value; }
}
//end Height
//start Width
private int _width;
[DefaultValue(150)]
[NotifyParentProperty(true)]
[RefreshProperties(RefreshProperties.Repaint)]
public int Width
{
get { return _width; }
set { _width = value; }
}
//end Width
//start FadeIn
private _FadeIn _fadein;
public enum _FadeIn
{
Slow,
Medium,
Fast
}
[DefaultValue(_FadeIn.Medium)]
[NotifyParentProperty(true)]
[RefreshProperties(RefreshProperties.Repaint)]
public _FadeIn FadeIn
{
get { return _fadein; }
set { _fadein = value; }
}
//end FadeIn
//start FadeOut
private _FadeOut _fadeout;
public enum _FadeOut
{
Slow,
Medium,
Fast
}
[DefaultValue(_FadeOut.Medium)]
[NotifyParentProperty(true)]
[RefreshProperties(RefreshProperties.Repaint)]
public _FadeOut FadeOut
{
get { return _fadeout; }
set { _fadeout = value; }
}
//end FadeOut
//start ShowDelete
private bool _showdelete;
[DefaultValue(true)]
[NotifyParentProperty(true)]
[RefreshProperties(RefreshProperties.Repaint)]
public bool ShowDelete
{
get { return _showdelete; }
set { _showdelete = value; }
}
//end View
}
}
Index.cshtml

CellList backed with ListDataProvider does not get redrawn on list change

I'm working on a project with GWT 2.1 and mvp4g. In a view, I'm using
a CellList backed with a ListDataProvider. If I pass a List with data to the constructor
when instantiating the ListDataProvider, the CellList shows this data.
The problem is that afterthat, the CellList never gets redrawn
whenever I change the list within the ListDataProvider. I don't know what I am
doing wrong or if I missing something.
Here is the code:
The UIBinder xml file:
<g:DockLayoutPanel unit="PX">
<g:west size="300">
<g:VerticalPanel styleName='{style.leftPanel}' spacing="8">
<g:Label>Expositores</g:Label>
<g:ScrollPanel addStyleNames='{style.exhibitorList}' width="250px" height="600px">
<c:CellList ui:field="exhibitorList" />
</g:ScrollPanel>
<g:Button ui:field="editExhibitorButton" addStyleNames='{style.button}'>Editar</g:Button>
</g:VerticalPanel>
</g:west>
...
The View class:
public class ExhibitorsAdminView extends Composite implements
ExhibitorsAdminPresenter.IExhibitorsAdminView {
interface Binder extends UiBinder<Widget, ExhibitorsAdminView> {}
private static final Binder binder = GWT.create( Binder.class );
private static class ExhibitorCell extends AbstractCell<Exhibitor> {
#Override
public void render(Cell.Context context, Exhibitor exhibitor,
SafeHtmlBuilder sb) {
if (exhibitor != null) {
sb.appendEscaped(exhibitor.getName());
}
}
}
private ListDataProvider<Exhibitor> exhibitorsDataProvider;
private SingleSelectionModel<Exhibitor> exhibitorsSelectionModel;
#UiField( provided = true )
CellList<Exhibitor> exhibitorList;
#UiField
Button editExhibitorButton;
// #UiField(provided = true)
// CellTable<Object> moduleList = new CellTable<Object>();
public ExhibitorsAdminView() {
exhibitorsSelectionModel = new
SingleSelectionModel<Exhibitor>(Exhibitor.KEY_PROVIDER);
exhibitorList = new CellList<Exhibitor>(new ExhibitorCell(),
Exhibitor.KEY_PROVIDER);
exhibitorList.setSelectionModel(exhibitorsSelectionModel);
exhibitorsDataProvider = new
ListDataProvider<Exhibitor>(getExhibitors());
exhibitorsDataProvider.addDataDisplay(exhibitorList);
exhibitorList.setPageSize(exhibitorsDataProvider.getList().size());
initWidget( binder.createAndBindUi( this ) );
}
public SingleSelectionModel<Exhibitor> getExhibitorsSelectionModel()
{
return exhibitorsSelectionModel;
}
public ListDataProvider<Exhibitor> getExhibitorsDataProvider() {
return exhibitorsDataProvider;
}
private List<Exhibitor> getExhibitors() {
List<Exhibitor> exhibitors = new ArrayList<Exhibitor>();
for (int i = 0; i < 10; i++) {
exhibitors.add(new Exhibitor(i, "aaaaaaaaaaaaaaa"));
}
return exhibitors;
}
public HasClickHandlers getEditExhibitorButton() {
return editExhibitorButton;
}
}
The presenter class:
#Presenter(view = ExhibitorsAdminView.class)
public class ExhibitorsAdminPresenter extends
BasePresenter<ExhibitorsAdminPresenter.IExhibitorsAdminView,
ExhibitorsEventBus> {
public interface IExhibitorsAdminView {
SingleSelectionModel<Exhibitor> getExhibitorsSelectionModel();
ListDataProvider<Exhibitor> getExhibitorsDataProvider();
HasClickHandlers getEditExhibitorButton();
}
private DispatchAsync dispatch = null;
#Inject
public ExhibitorsAdminPresenter(final DispatchAsync dispatch) {
this.dispatch = dispatch;
}
#Override
public void bind() {
getView().getExhibitorsSelectionModel().addSelectionChangeHandler(
new SelectionChangeEvent.Handler() {
public void onSelectionChange(SelectionChangeEvent event) {
Exhibitor selected =
getView().getExhibitorsSelectionModel().getSelectedObject();
if (selected != null) {
Window.alert("You selected: " + selected.getName());
}
}
});
getView().getEditExhibitorButton().addClickHandler(
new ClickHandler() {
public void onClick(ClickEvent event) {
}
});
}
public void onGoToExhibitorsAdmin() {
}
public void onLoadExhibitors() {
dispatch.execute(new GetExhibitors(), new
AsyncCallback<GetExhibitorsResult>() {
public void onSuccess(GetExhibitorsResult result) {
getView().getExhibitorsDataProvider().setList(
result.getExhibitors());
getView().getExhibitorsDataProvider().refresh();
}
public void onFailure(Throwable caught) {
GWT.log("error executing command ", caught);
}
});
}
}
Thanks.
I solved it. I'm sorry, it was an issue related with mvp4g. I was doing something wrong that was causing to have to different instances of the view where the CellList was placed. The update operations I was doing on the list of the ListDataProvider were being done on the view instance that wasn't being shown.
You have to manipulate the list by getting it first of your provider like provider.getList().add(...). See How to add or remove a single element from/to CellList? for a minimal example.
Just call exhibitorsDataProvider.refresh() after all operations with underlying list.