AutoRefresh on DynamicData and ReactiveUI - dynamic-data

I'm trying to observe when a value of IsEnabled in one of Results changes:
SourceList<Models.Result> mySource = new SourceList<Models.Result>();
var isEnabledChangedOperation = mySource.Connect().AutoRefresh(r => r.IsEnabled).Select(_ => TestFunction());
but "r => r.IsEnabled" is underlined and gets an error "Cannot convert lambda expression to type 'TimeSpan?' because it is not a delegate type"
What's wrong?

I suspect most likely you didn't put INotifyPropertyChanged on your Result class.
I had the same error with your sample code until I added that.

The solution without AutoRefresh():
To add and implement INotifyPropertyChanged or ReactiveObject to Models.Result
and set:
var isEnabledChangedOperation = mySource
.Connect()
.WhenPropertyChanged(x => x.IsEnabled)
.Subscribe(x => TestFunction());

Related

asp.net, razor: when model is returned it will construct it anew

i am inflating my view like this
public ActionResult Tagging(int id, ItemType itemType, bool autoCloseWindow = false, bool refreshOpener = false)
{
var model = new TaggingViewModel(id, itemType);
return View("Tagging", model);
}
I give the params id and itemtype to retrieve the correct data.
I display the data (correclty) like so:
<td>
#Html.CheckBoxFor(m => m.MainNodes[i].children[y].IsChecked, new { #class = "langCheck" })
#Html.HiddenFor(m => m.MainNodes[i].children[y].ItemId)
#Html.HiddenFor(m => m.MainNodes[i].children[y].GlobalTaggingId)
#Html.HiddenFor(m => m.MainNodes[i].children[y].ItemType)
</td>
But if I press save in my form field the model is returned empty:
I found out that the reason is that in the params of the saveTagging method I instiate the model anew, but with out the params (as you cannot pass them here) and therefore get an empty model returned.
but:
1.) How do I give it params?
2.) Even if I were to give the params say statically, I dont want the old model returned, I want the altered model from the front end returned.
As it turns out, I was doing ALMOST everything right.
You CANNOT simply return the whole model with an ID, but you can simply return the property from the model that you need. Meaning I changed the params in my Action Result from:
public ActionResult SaveTagging(TaggingViewModel taggedModel, bool autoCloseWindow = false)
to:
public ActionResult SaveTagging(List<NodeModelWithCheckBoxes> MainNodes, bool autoCloseWindow = false)
With
List<NodeModelWithCheckBoxes> MainNodes
being the list with the values that were returned null. This list ofc is part of my model taggedModel
This way, it isnt instantiated anew and all my values are getting passed into this object.

MvvmCross.Forms - Default Spinner will not exit

This bug exists in the Sample files (StarWarsSample) and I have been trying to remove it for SEVERAL hours... any advice is appreciated:
Using MvvmCross.Forms
I have an MvxListView which has RefreshCommand bound to a command. I have confirmed it fires. When the MvxListView is pulled down (both iOS and Android) a spinner appears. However it never disappears. I do not have any exceptions being thrown. If I raise a dialog it appears over the spinner, but then once cancelled the spinner remains. My ListView is dynamically updating fine. Just the spinner never disappears... I'm assuming it's coming from some specific function in MVVMCross/Forms but i cannot seem to find any reference to it.
Here's the relevant code (in it's current state after trying different approaches)
<views:MvxListView
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
SelectionMode="None"
ItemsSource="{mvx:MvxBind BtDevices}"
ItemClick="{mvx:MvxBind BtDeviceSelectedCommand}"
IsPullToRefreshEnabled="True"
RefreshCommand="{mvx:MvxBind RefreshBtDevicesCommand}"
ItemTemplate="{StaticResource DeviceNameTemplate}"
RowHeight="{x:OnPlatform Android=55, iOS=55, UWP=40}"
BackgroundColor="LightBlue"
SeparatorVisibility="None">
</views:MvxListView>
public HomeViewModel(...){
BtDevices = new MvxObservableCollection<BtDevice>();
BtDeviceSelectedCommand = new MvxAsyncCommand<IBtDevice>(BtDeviceSelected);
FetchBtDevicesCommand = new MvxCommand(() =>
{
FetchBtDeviceTask = MvxNotifyTask.Create(LoadDevices, onException: OnException);
RaisePropertyChanged(() => FetchBtDeviceTask);
});
RefreshBtDevicesCommand = new MvxCommand(()=>
{
RefreshDeviceTask = MvxNotifyTask.Create(RefreshBtDevices, OnException);
RaisePropertyChanged(() => RefreshDeviceTask);
});
}
private async Task RefreshBtDevices()
{
IsBusy = true;
var result = await _btService.LoadDevices(_nextPage);
foreach (var d in result.Where(d => BtDevices.FirstOrDefault(i => i.Id == d.Id) == null))
{
BtDevices.Add(d);
}
IsBusy = false;
await RaisePropertyChanged(() => RefreshDeviceTask);
await RaisePropertyChanged(() => RefreshBtDevicesCommand);
}
From the docs you need to bind the IsRefreshing property of the list view.
Gets or sets a value that tells whether the list view is currently refreshing
Something like this:
IsRefreshing="{mvx:MvxBind IsBusy}"
or if you are using an MvxNotifyTask:
IsRefreshing="{mvx:MvxBind RefreshDeviceTask.IsNotCompleted}"
Here you have more informaion, even though it uses directly ListView on the example the same can be applied to MvxListView given that it inherits from ListView.
HIH

CSVHelper generic ClassMap with System.Reflection

I'm trying genericly map the properties of my class to the column names of the CSV without the need to write every single line in the ClassMap like
Map(rm => rm.PUsrCrRequestedObject).Name("#P_USR_CR_RequestedObject");
because we have very much columns with mostly the same type of mapping.
So i tried the following code:
var classMap = csv.Configuration.AutoMap<RequestMonitoring>();
foreach (var property in typeof(RequestMonitoring).GetProperties())
{
var columnName = property.Name switch
{
"PNdsPn" => "$P_NDS_PN",
{ } x when x.StartsWith("PUsrCr") => property.Name.Replace("PUsrCr", "#P_USR_CR_"),
_ => property.Name
};
classMap.Map(requestMonitoring => property).Name(columnName);
}
I don't get an error but if i debug the ClassMap the code above hasn't got any effect.
So the question is how can i fix the code snippet or if it's not possible maybe how to apply the same name conversion for every property
Try this.
classMap.Map(typeof(RequestMonitoring), property).Name(columnName);

How to disable WinForms button if SourceList is empty

I've been using ReactiveUI with WinForms and just did the switch to DynamicData, using a SourceList instead of a ReactiveBindingList.
As per this issue, WinForms IBindingList Collection Support was added.
I have a listbox which I bind to a list of strings. In order to make it work with WinForms, I've created a BindingList which is connected to the SourceList:
var Images = new SourceList<string>();
var ImagesBindableWinForms = new BindingList<string>();
Images.Connect().Bind(ImagesBindableWinForms).Subscribe();
The BindingList is then bound to the listbox as follows, which works swell:
d(this.Bind(ViewModel, x => x.AdInfo.ImagesBindableWinForms, x => x.listImages.DataSource));
There is a button to remove items form the list. It should be disabled if the list is empty. Before switching to SourceList, this used to work:
ViewModel.DeleteImageCmd = ReactiveCommand.Create(DeleteImage, ViewModel.CanDeleteImage());
public IObservable<bool> CanDeleteImage()
{
var canDeleteImage = this.WhenAnyValue(vm => vm.AdInfo.Images.Count)
.Select(x => x > 0);
return canDeleteImage;
}
The code would enable or disable the button depending on the list count.
The same code no longer works. I guess no event is fired when the count is updated.
How would I go about disabling the button if the SourceList is empty?
It is necessary to create an ObservableCollectionExtended and bind that to the SourceList as well. The CanDeleteImage should use that instead of the SourceList, or the BindingList:
var ImagesBindable = new ObservableCollectionExtended<string>();
Images.Connect().Bind(ImagesBindable).Subscribe();
public IObservable<bool> CanDeleteImage()
{
var canDeleteImage = this.WhenAnyValue(vm => vm.AdInfo.ImagesBindable.Count)
.Select(x => x > 0);
return canDeleteImage;
}
Only disadvantage is that I now have three lists, but it works.

Moq - Using MockRepository.Verify() With Times

I'm looking to see if it's at all possible to specify a Times enum value in the setup of a mocked property that can then be exercised by the MockRepository.Verify() method at the Assert block of my AAA-style test. My current code reads like so:
// Arrange
var repository = new MockRepository(MockBehavior.Default);
var mockLogin = repository.Create<Login>();
mockLogin.SetupProperty(d => d.LoginID, 1515254);
var mockIApplicationEventLogService = repository.Create<IApplicationEventLogService>();
mockIApplicationEventLogService.Setup(d => d.InsertApplicationEventLog(It.IsAny<ApplicationEventLog>())).Verifiable();
var mockILoginResetFailedService = repository.Create<ILoginResetFailedService>();
mockILoginResetFailedService.Setup(d => d.GetLoginResetFailedByLoginID(It.IsAny<int>())).Returns((LoginResetFailed)null);
var mockApplicationEventLog = repository.Create<ApplicationEventLog>();
mockApplicationEventLog.SetupAllProperties();
var LoginWorkflowService = new LoginWorkflowService()
{
ApplicationEventLogService = mockIApplicationEventLogService.Object,
ApplicationEventLog = mockApplicationEventLog.Object,
LoginResetFailedService = mockILoginResetFailedService.Object
};
// Act
var result = LoginWorkflowService.CheckLoginResetFailuresLock(mockLogin.Object, It.IsAny<Guid>(), It.IsAny<SecurityPolicy_Aggregate>(), It.IsAny<string>(), It.IsAny<string>());
// Assert
result.Should().BeTrue();
mockIApplicationEventLogService.Verify(d => d.InsertApplicationEventLog(It.IsAny<ApplicationEventLog>()), Times.Never);
What I'd like to be able to do is call repository.Verify() at the end, but with my current code the Verify() call will expect InsertApplicationEventLog to have been called when in fact I expect it to never have been called. I have tried passing Times.Never into the Setup method for mockIApplicationEventLogService but it doesn't seem that there's a method override that takes it. Am I limited to individual Verify() calls if I have mocks in my repository that should never be called, or is there a way around this?
It appears as Nkosi said, it's not currently possible to do this. There is a request for this at the following URL:
https://github.com/moq/moq4/issues/373

Resources