How to handle ViewModel and Database in C#/WPF/MVVM App - sql

I have a task management program with a "Urgency" field. Valid values are Int16 currently mapped to 1 (High), 2 (Medium), 3 (Low), 4 (None) and 99 (Closed). The urgency field is used to rank tasks as well as alter the look of the items in the list and detail view.
When a user is editing or adding a new task they select or view the urgency in a ComboBox. A Converter passes Strings to replace the Ints. The urgency collection is so simple I did not make it a table in the database, instead it is a, ObservableCollection(Int16) that is populated by a method.
Since the same screen may be used to view a closed task the "Closed" urgency must be in the ItemsSource but I do not want the user to be able to select it. In order to prevent the user from being able to select that item in the ComboBox but still be able to see it if the item in the database has that value should I...
Manually disable the item in the ComboBox in code or Xaml (I doubt it)
Change the Urgency collection from an Int16 to an Object with a Selectable Property that the isEnabled property of the ComboBoxItem Binds to.
Do as in 2 but also separate the urgency information into its own table in the database with a foreign key in the Tasks table
None of the above (I suspect this is the correct answer)
I ask this because this is a learning project (My first real WPF and first ever MVVM project). I know there is rarely one Right way to do something but I want to make sure I am learning in a reasonable manner since it if far harder to Unlearn bad habits
Thanks
Mike

I would favor option 2. Sounds very MVVM-stylish to me.
Option 3 would be favorable, when there are other applications or when you have reports accessing the "Urgency" field. Reason: Otherwise you will need to duplicate the knowledge of mapping between Int16 and their meaning. Move the knowledge to the database to keep it in one place.
Maybe consider Enums to make the code more expressive:
enum Urgency { High=1, Medium=2, Low=3, Closed=99 };
This way you will have something nice looking for evaluating the IsEnabled property like this:
if (urgency == Urgency.Closed) return false;
When you need to store the numeric value of the enum, you will need to make a cast to Int16 beforehand.

I think that I'd first fix this in the view. Have a TextBlock that displays "Closed", and a ComboBox that displays the other values, and then use a data trigger to set IsVisible on both depending on whether or not Urgency is 99.
I'd do this not because it's the best technical solution (it's probably not) but because it's (possibly) the best UI solution. If the user can't ever modify a closed item, it's a little misleading to display "Closed" even in a disabled ComboBox, since the ComboBox means, visually, "Here's something you can change." That it's disabled just prompts the user to wonder what he has to do to enable it. Using a TextBlock is an unambiguous way of saying "this is just how it is."

Related

How to keep initial value of a field after POST is done

I have an Oracle Forms app. There is a form with a date field and I need to keep it initial value (when form is loaded), to compare it with actual value in the field. Also there is a button on the form, that posts changes.
I've tried to store initial value with global variable and check if it's changed, also I've tried to simply check that :system.record_status != 'QUERY' to track if date is modified.
Problem that at the moment, when button is pressed and post is done the values of all global variables become null, so I can't compare the initial value with the new one and :system.record_status becomes 'QUERY' again, and I don't see any more if user modified something.
How to keep the initial values or track that data was changed, doesn't matter if user posts changes or not?
This:
Problem that at the moment, when button is pressed and post is done the values of all global variables become null, so I can't compare the initial value with the new one
doesn't work that way. Post (if you refer to POST built-in) (nor COMMIT, as we're at it) doesn't clear global variables. Explicitly setting it to NULL does, so - check the form whether you've done it somewhere in your code. How? Run the form in debug mode, trace its execution and see what's going on.
Another thing that might be going wrong is that global variables's datatype is CHAR so - if you plan to compare it to a different datatype value, you should perform conversion. As it is a date value, consider applying TO_DATE function to the global variable with appropriate format mask.
this will work:
IF GET_ITEM_PROPERTY(:SYSTEM.CURSOR_ITEM,UPDATE_COLUMN) ='TRUE' THEN
Copy(Get_Item_Property(itm, Database_Value), :System.Cursor_Item);

Calling MM42, dirty assign of variables in SAPLCTMS for atnam and atwrts - Any experience?

In a custom program I call the retail material transaction (change, so MM42).
The user could change attribute values ( meaning ATWRT ) which are placed on the screen.
The debugger tells me, that there are a lot of variables, some seem to be the right ones, IF ONLY ONE atwrt of an atnam is changed. In case of multiple atwrt changes on more than one atnam, my dirty assign would only know the LAST ATNAM and it's new ATWRT.
This question adresses those developers, which might have already done this and may give me a hint, which one of the dozens of tables could track all the atnams and atwrts and also being possible to assign it in my calling program,after the MM42 returns.
IS there anybody in here, who may have done this, so I could save a bit of (maybe even lost) time ?

Using placeholder template in core data without saving the placeholders?

I am wondering if its possible to have a core data and use a NSFetchedResultsController to display template holders; without saving the placeholder template holder to core data.
I am writing an app where a table view will have the following characteristics
Maximum amount of rows (ie: 8)
Each cell uses a partial view, a single table cell instance with clickable buttons;
A user clicking on the buttons replaces the content for each button
When a user comes to save the data it stores the content in the exact places, but crucially it should not save the blank placeholder state; but still respect the placement positioning.
IE: Lets say a user picks the right button for cell 1 and saves it;
when the the user returns to this dataset sometime in the future, it
should have the imagery and data in the correct place; but still keep
the left button for cell 1 empty (placeholder)
The reason I don't want to save the placeholder content is because I consider this data to be "dirty"; its meaningless and has no place in a dataset; its a view; not data.
Currently:
I create data using insertInManagedObjectContext but do not save it until the user has pressed save.
Each matchRow has many fighters. This relationship is a NSOrderedSet, managed by core data.
The problems I'm having are;
NSFetchedResultsController only respects saved core data items; and ignores the placeholder data.
If a user only saves one (right button) data, the NSOrderedSet sees this as the first (left button) data; which is in correct
If I strip out all the placeholder structures from the core data in a pre-save action, the effect is that the order the user wanted is now lost and it causes a crash when reloading because the size of the arrays are incorrect.
Currently the only way around this is to stop using
NSFetchedResultsController and use a NSArray; and put the placeholders into the array too, then save everything, (dirty objects) and all.
I really don't want to do that. The placeholder content isn't meant to be saved.
I've been reading a blog post on using separate classes for special cases where he has different data sources; and uses the technique to separate class for the "empty" case, and to set it as the table view’s datasource when it's empty.
Whilst this is interesting, it only solves it for an empty case; when my requirement is that the partial view should handle all states; empty data and partial data.
One idea I have is that we need another entity between our record and our match rows;
Match - MatchRowMeta - Fighter
Not sure what the relationship would be
where;
RowMeta {
record.obj (relationship)
fighters.obj (relationship)
positionID (integer) - which button has been set
}
But I don't think this is the best way to do it; it seems expensive and a lot of heavy lifting to do something relatively simple.
Thus, my question:
Is it possible to have a table view made up of template holders; where the structure is saved to core data but none of the empty (dirty) objects are saved; plus NSFetchedResultsController will respect the structure; even when its empty or partially empty?
Edit: Added entity diagram

Filling parameter with value from Zeconfig_var table

I have the following selection parameter:
PARAMETERS: p_ver(2) AS LISTBOX VISIBLE LENGTH 5.
I would like to populate it with the results from a ZECONFIG_VAR table.
At what point would I do this. Selection Screen Output, Start of Selection, or other. I am trying to allow users the ability to decide what version of the web service they would like to call. The config table will have different url's for the different versions.
I have looked at this Answer and the tutorial provided does not make sense to me.
I would do it at the event INITIALIZATION
However, it may be even easier to just create a search-help, and assign it to p_ver using the following:
parameters: p_ver(2) visible lenghth 5 MATCHCODE OBJECT zshelpname.
Esti is right that you probably want to fill an internal table from the DB table during INITIALIZATION.
But to the populate the listbox parameter, you need to put the call to VRM_SET_VALUES in AT SELECTION-SCREEN OUTPUT.

How can I let user input a value not listed in a pull-down list?

This is really a "best practices" question: Assume I have a dynamically generated pull-down list populated with suggested values (e.g. [Vanilla, Strawberry, Chocolate]). How do I give the user the option of selecting one of the suggested values OR inputting a new value (e.g. "Rocky Road")?
One approach would be to populate the list with a None of the Above entry ([Vanilla, Strawberry, Chocolate, None of the Above]) and write my controller so that if None of the Above is selected, it will then render a form with a text field instead of the pull-down. But that feels horribly clunky.
Is there some elegant GUI technique for this sort of thing, perhaps using JQuery?
I suggest you to use simple text input with jquery autocomplate plugin don't use pull-down list. Autocomplate can work with datas you populated. If user inputs a new value, in controller use find_or_create_by dynamic activerecord method.