What is the MVC equivalent of this code: - model-view-controller

Here's the easy pseudo-code:
void TextBox1Changed()
{
//If the text isn't a number, color it red
if (!IsValidNumber(TextBox1.Text)
TextBox1.Color = Pink;
else
TextBox1.Color = WindowColor;
}
What's the MVC enterprisey version?

Not trying to be language specific, but the idea is to create a number text control that knows if the value is valid. It's easy to get hung up on the exact roles of M, V, and C. However, for all practical purposes, it makes sense to combine the View and the Controller for Desktop like applications. Swing took that approach because the controller and view had very tight coupling and it made sense to combine them into one. Read up this nice discussion on c2 about the topic.
class NumberTextBox extends TextBox {
bool isValid() {
return IsValidNumber(this.Value);
}
}
ageTextBox = new NumberTextBox();
ageTextBox.addChangeHandler(function() {
this.Color = this.isValid ? WindowColor : Pink;
});

Related

ComboBox.Item.add(USB1) switch language----- globalization - VS 2019 WPF

I added ComboBox from MainWindow_OnContentRendered, when I start the program, and how ComboBox.Item will find the resource file to change different language?> .How can I put WPF ComboBox content globalization.Thank you.
hello.
A.
1.
public void MyComboBox()
{
ComboBox.Item.add(USB1)
ComboBox.Item.add(USB2)
ComboBox.Item.add(USB3)
}
2.
MainWindow_OnContentRendered
{
MyComboBox();
}
B.
//ResourceHelper.cs
public static void LoadResource(string ) {
var = (from d in _Resourcelist where d.ToString().Equals() select d).FirstOrDefault();
App.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri(langType, UriKind.RelativeOrAbsolute) });
Thread.CurrentThread.CurrentCulture = cultureInfo;
hread.CurrentThread.CurrentUICulture = cultureInfo;}
The question sounds quite simple but is quite difficult to answer. I've just started a new WPF application from scratch, so I thought about the issue of switching to a different language at runtime in general. Of course you have to set CurrentCulture and CurrentUICulture like you do in your example. But what about the controls and their textual content?
My solution is a recursive method that I call with MainWindow.Content as parameter, and then it iterates deeper and deeper through the hierarchy of controls:
private static void ReloadAllText(object root)
{
if (root is TextBlock textBlock1)
{
UpdateBinding(textBlock1, TextBlock.TextProperty);
}
else if (root is ContentControl contentControl)
{
if (contentControl.Content is string)
{
UpdateBinding(contentControl, ContentControl.ContentProperty);
}
else
{
ReloadAllText(contentControl.Content);
}
}
else if (root is Panel panel)
{
foreach (var child in panel.Children)
{
ReloadAllText(child);
}
}
else if (root is ItemsControl itemsControl)
{
for (int cnt = 0, cntMax = VisualTreeHelper.GetChildrenCount(itemsControl); cnt < cntMax; cnt++)
{
if (VisualTreeHelper.GetChild(itemsControl, cnt) is TextBlock textBlock2)
{
ReloadAllText(textBlock2);
}
}
foreach (var item in itemsControl.Items)
{
ReloadAllText(item);
}
}
else if (root is Decorator decorator)
{
ReloadAllText(decorator.Child);
}
else if (root is IRaiseLanguageChanged customItem)
{
customItem.RaiseLanguageChanged();
}
}
The method consists of several branches:
For TextBlock (which is also used by default as the text display element inside other, more complicated controls), the Text property is set to the new value. In my case, I just update the binding. In your case, the new text may have a different source, I don't know your architechture.
For ContentControl (which is any control that has a Content property), it depends: If the content is just a string, I can set it to the new value right away. If it's more complex, then I have to recurse deeper.
For Panel (which is the base class for StackPanel, DockPanel, Grid etc.), I just recurse for each child element.
For ItemsControl (so also for your ComboBox!), I recurse for each item. I added the VisualTree part only because I have a control template for an empty list box consisting of only a TextBox saying "no items". If you bind ItemsSource to an enum type, you must renew the ItemsSourceProperty binding.
For Decorator (e.g. Border), I recurse for its single child.
For custom/self-made controls, I have defined a custom interface IRaiseLanguageChanged, so they must implement a RaiseLanguageChanged() method and handle the language switch themselves. After all, a control itself knows best what to do when the language changes.
This reflects only the set of controls I'm currently using. If you have additional control types, then you have to add respective branches. Please post them here, if you have any good ideas!

Calling Several Functions Linked With Classes at Certain Times with AS3

I'm working on a random wave system for a game. The idea is that every 1000 points a movement pattern would be selected from around 50 possibilities. This would affect the speed, direction, and image of the selected item. I have devised a method that I think will work, but I'm unsure if this is going to cost too much memory to run.
public class engine extends MovieClip {
private var countK:Number = 0;
private var newWave:Boolean = true;
public function engine() {
stage.addEventListener(Event.ENTER_FRAME, update);
}
private function update():void {
checkCount();
checkNew();
}
private function checkCount():void {
if (count => 1000) {
newWave=true;
count = 0;
}
}
private function checkNew():void {
if(newWave) {
randomNumber();
newWave=false
}
}
Above is my quick idea of getting a random number to be generated every 1000 points. Points can be added in any way you want (just add say 20 to "Score" and 20 to "count" at the same time). Where I can a random number function in checkNew, I won't be pulling another function, it's simply there for the sake of legibility.
var newEnemy:mEnemy =new mEnemy();
stage.addChild(newEnemy);
EnemyArray.push(newEnemy);
trace(EnemyArray.length);
Above is some code that can add an instance of mEnemy to the stage. Now where I'm starting to loose it is, how can I translate the random number into a viable method of changing mEnemy's behaviour?
Is it wise to have 50 functions inside the mEnemy class and just before I addChild, I do something like newEnemy.WAVEfuncton1(); ? If that is the case, can I save code by getting it to select the function without writing a whole bunch of if statements?
Instead of;
if (randomN==1) {
newEnemy.WAVEfunction1();
}
if (randomN==2) {
newEnemy.WAVEfunction2();
}
....
Can I do;
newEnemy.WAVEfunction[randomN]();
This is also assuming that using functions inside the enemy is the best idea. Is it better to have the behaviours inside the engine class instead?
As you can see, I'm no programmer. I'm very new to this sort of thinking and I don't want to create a mistake that will destroy the performance of the game (not to mention picking up bad habits too!).
If you have taken the time to read this question, thank you! If you tolerate my ignorance, then thank you even more!
If the wave functions are just creating a single enemy of a certain type, it might make more sense to make an array with the details of each type like this: (I'm guessing at how your enemies work of course)
private const ENEMY_TYPES:Array = [
{speed:1, direction:90, image:1},
{speed:2, direction:45, image:2}
]
then change mEnemy() to set itself up according to the details you give it:
public function mEnemy(details:Object) {
mySpeed = details.speed;
...
That way, you can just write new mEnemy(ENEMY_TYPES[randomN]);
Alternatively, if you do need to have lots of separate wave functions, you can use the [ ] array access operator to access the properties of an object such as newEnemy by name (or this to reference the current object):
var exampleProperty:String = "Hello.";
this["exampleProperty"];
So you can run your wave functions by writing:
newEnemy["WAVEfunction" + String(randomN)]();
A 2-year old question and rather non-actual already but let me try myself here as I have just signed up.
As I understood, what are you proposing to do here is writing all 50 behaviour methods for each kind of Enemy, which is of course not good.
First, you can add the "behaviour" entity. So each enemy now has a behaviour property.
Next, you have to create a separate Behaviour class or interface, which will have 50 subclasses (Behaviour1...Behaviour50), each subclass implementing its own run() method. Note that this way you will be able to add or remove behaviours without touching anything else. A basic implementation would look like this:
public class Behaviour() {
public function run(e:Enemy):void {
e.y += 10;
}
}
So you see, it's not like enemy is doing something. It's the Behaviour that does something with the enemy it was passed to.
Next, you need a mechanism to get the proper subclass from a given random number.
What you need is a Factory - a static class that will return different types of Behaviours based on input params. Something like this:
public class BehaviourFactory {
public static getBehaviour(n:int):Behaviour {
switch(n) {
case 1: return new Behaviour1();
case 2: return new Behaviour2();
// etc.
}
}
}
Instead of having 50 choices inside a switch, you can also use the class definition:
var c:Class = getDefinitionByName('Behaviour' + your_random_number) as Class;
return new c;
(In further implementatons it can be cached, stored in an Array etc.) After you have a Factory, you just do:
var b:Behaviour = BehaviourFactory.getBehaviour(your_random_number);
Next, you can use different approaches depending of how exactly the behaviour changes. For example, if the enemy is born with a specific current behaviour and it doesn't change during the enemy's lifetime, you can just assign one of Behaviour subclasses to the Enemy's behaviour property:
public class Enemy {
public var behaviour:Behaviour;
public function Enemy(b:Behaviour) {
this.behaviour = b;
}
}
var e:Enemy = new Enemy(BehaviourFactory.getBehaviour(random_number));
e.behaviour.run(e);
This property of course can also be changed dynamically so the next time it is run the enemy will behave differently.
If the behaviour is global for all enemies and changes for all of them at once, you don't event need to have a property in an Enemy object. You just have a global Behaviour object and pass there an Enemy instance:
var e:Enemy = enemy_list[i];
current_behaviour.run(e);
it will take care of processing each active enemy according to the currently chosen behaviour.
Finally, there's more interesting way to implement behaviours. Suppose you have several behaviour types that don't have anything in common. Say, the Enemy can be Crawling, Flying, Shooting and Poisonous. So let's say you're attempting to implement all possible combinations: Flying, FlyingShooting, FlyingPoisonous, FlyingShootingPoisonous, etc. You would have to create a Behaviour subclass for each of these combinations despite them having very common basic parts.
There's an other way to go, called the Decorator pattern. You simply write a method for each single quality. Whenever you need a combination of qualities, you simply create object with first quality and wrap it into the object with the second quality and wrap it into the object with the third quality etc. So your base Behaviour class needs one addition:
public class Behaviour {
private var parent_bhv: Behaviour;
public function Behaviour(bhv:Behaviour = null) {
if (bhv) this.parent_bhv = bhv;
}
public function run(e:Enemy):void {
e.y += 10; // do what we need to do
if (this.parent_bhv) this.parent_bhv.run(e); // pass to a next bhv.
}
}
Let's create compound behaviour of number 1, 3 and 15:
var decorated_behaviour:Behaviour = BehaviourFactory.getDecoratedBehaviour([1, 3, 15]);
let's also add the corresponding BehaviourFactory method:
public class BehaviourFactory {
public static function getDecoratedBehaviour(bhv_list:Array):Behaviour {
var b:Behaviour = null;
for (var i:int = 0; i < bhv_list.length; i++) {
var c:Class = getDefinitionByName('Behaviour' + bhv_list[i]) as Class;
b = new c(b);
}
return b;
}
}
Now you're all set without having to code all possible combinations!

Users restrictions for associated data in ASP Membership

I have a site I'm porting to MVC to clean up the code and simplify things. I use the asp membership and profile providers, but I'm wondering if I'm doing this correctly for my situtation. I'm pretty new to MVC, so I wan to get this right in the early stages.
Users are individuals and they are part of larger "institutions" that they either set up or pick at registration. In this case, the institution is a winery. I want the users to be able to view all wines from every winery, but only edit ones that belong to them.
What's the best way to do this? Right now I render the link to the edit field in my index view based on their instution ID and the producer ID. I feel like a data annotation might work better here, but I don't exactly how to implement that for a group of wines. Do I need multiple providers? I use roles to limit the editing, but right now an editor role could manually enter the path of another wine to edit it when that wine doesn't belong to them.
Any pointers here would be awesome. I know I can do it in the controller methods, but I'm looking for the 'right' way to do it. Thanks.
I'm running into the same issue at work right now, and the best proposed solution we have right now is implementing an "ownership" table. You won't be able to solve this using roles.
So basically you have an owner ID, owned object's ID, and the type of objects ID all held together. Lets take an edit request for example. We know that you can only edit the data person X owns, so we have a stored procedure that if a key combination exists in our ownership table where person.ID = owner ID, and item.ID = object ID, and item.TypeID = objectTypeID. If it exists, it goes along performing its edits, otherwise it returns an error.
You can use this scheme to return ownership lists, user validation, and a host of other issues you may come across. You probably won't need the ObjectTypeID if you only have one type's ownership being tracked. Hope this helps!
I figured this out by applying a custom AuthorizeAttribute to the edit, delete, and create actions.
Here is what I ended up doing:
public class ProducerEditAttribute : AuthorizeAttribute
{
private vfContext db = new vfContext();
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
bool bAdmin = filterContext.HttpContext.User.IsInRole("admin");
bool bProdEdit = filterContext.HttpContext.User.IsInRole("producereditor");
bool bProd = filterContext.HttpContext.User.IsInRole("producer");
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
{
if (bAdmin)
{
//authorized
}
if (bProdEdit || bProd)
{
//check for current wine belonging to the producer.
Producer currentProd = db.Producers.Find(Profile.GetProfile(filterContext.HttpContext.User.Identity.Name).InstitutionID);
Wine currentWine;
object WineID;
if (filterContext.RouteData.Values.TryGetValue("id", out WineID))
{
currentWine = db.Wines.Find(int.Parse(WineID.ToString()));
if (currentProd.Wines.Contains(currentWine) && bProdEdit)
{
//authorized
}
else if (bProd)
{
var result = new ViewResult();
result.ViewName = "Login.cshtml"; //this can be a property you don't have to hard code it
result.MasterName = "_Layout.cshtml"; //this can also be a property
result.ViewBag.Message = "You do not have permission for add/edit/delete funciontionality. Please request.";
filterContext.Result = result;
}
else
{
var result = new ViewResult();
result.ViewName = "Login.cshtml";
result.MasterName = "_Layout.cshtml";
filterContext.Result = result;
}
}
}
else
{
var result = new ViewResult();
result.ViewName = "Login.cshtml";
result.MasterName = "_Layout.cshtml";
}
}
}
}

Entity Framework 4 - List<T> Order By based on T's children's property

I have the following code -
public void LoadAllContacts()
{
var db = new ContextDB();
var contacts = db.LocalContacts.ToList();
grdItems.DataSource = contacts.OrderBy(x => x.Areas.OrderBy(y => y.Name));
grdItems.DataBind();
}
I'm trying to sort the list of the contacts according to the area name that is contained within each contact. When I tried the above, I get "At least one object must implement IComparable.". Is there an easy way instead of writing a custom IComparer?
Thanks!
try this:
public void LoadAllContacts()
{
var db = new ContextDB();
var contacts = db.LocalContacts.ToList();
grdItems.DataSource = contacts.OrderBy(x => x.Areas.OrderBy(y => y.Name).First().Name);
grdItems.DataBind();
}
this will order the contacts by the first area name, after ordering the areas by name.
Hope this helps :)
Edit: fixed error in code. (.First().Name)
I was in a discussion with #AbdouMoumen but in the end I thought I'd provide my own answer :-)
His answer works, but there two performance issues in this code (both in the answer as in the original question).
First, the code loads ALL contacts in the db. This may or may not be a problem, but in general I would recommend NOT to do this. Many modern controls support paging/filtering out of the box, so you'd be better off supplying an not-yet-evaluated IQueryable<T> instead of List<T>. If however you need everything in memory, you should delay the ToList to the last possible moment.
Second, in AbdouMoumen's answer, there is a so-called 'SELECT N+1' problem. Entity Framework will by default use lazy loading to fetch additional properties. I.e. the Areas property will not be fetched from the database until it's accessed. In this case this will happen in the controls 'for loop', while it's ordering the result set by name.
Open up SQL Server Profiler to see what I mean: you will see a SELECT statement for all the contacts, and an additional SELECT statement for each contact that fetches the Areas for that contact.
A much better solution would be the following:
public void LoadAllContacts()
{
using (var db = new ContextDB())
{
// note: no ToList() yet, just defining the query
var contactsQuery = db.LocalContacts
.OrderBy(x => x.Areas
.OrderBy(y => y.Name)
.First().Name);
// fetch all the contacts, correctly ordered in the DB
grdItems.DataSource = contactsQuery.ToList();
grdItems.DataBind();
}
}
Is it one to one relation (Contact->Area)?
if yeah then try the following :
public partial class Contact
{
public string AreaName
{
get
{
if (this.Area != null)
return this.Area.Name;
return string.Empty;
}
}
}
then
grdItems.DataSource = contacts.OrderBy(x => x.AreaName);

Using DataObjectTypeName in DataObjectSource

The functionality I am trying to use is:
- Create a ObjectDataSource for selection and updating controls on a web page (User Control).
- Use the DataObjectTypeName to have an object created that would send the data to an UpdateMethod.
- Before the values are populated in the DataObjectTypeName’s object, I would like to pre-populate the object so the unused items in the class are not defaulted to zeros and empty strings without me knowing whether the zero or default string was set by the user or by the application.
I cannot find a way to pre-populate the values (this was an issue back in 2006 with framework 2.0). One might ask “Why would anyone need to pre-populate the object?”. The simple answer is: I want to be able to randomly place controls on different User Controls and not have to be concerned with which UpdateMethod needs to handle which fields of an object.
For Example, let’s say I have a class (that reflects a SQL Table) that includes the fields: FirstName, LastName, Address, City, State, Zip. I may want to give the user the option to change the FirstName and LastName and not even see the Address, City, State, Zip (or vice-versa). I do not want to create two UpdateMethods where one handled FirstName and LastName and the other method handles the other fields. I am working with a Class of some 40+ columns from multiple tables and I may want some fields on one screen and not another and decide later to change those fields from one screen to another (which breaks my UpdateMethods without me knowing).
I hope I explained my issue well enough.
Thanks
This is hardly a solution to the problem, but it's my best stab at it.
I have a GridView with its DataSourceID set to an ObjectDataSource.
Whenever a row is updated, I want the property values in the object to be selectively updated - that is - only updated if they appear as columns in the GridView.
I've created the following extension:
public static class GridViewExtensions
{
public static void EnableLimitUpdateToGridViewColumns(this GridView gridView)
{
_gridView = gridView;
if (_gridView.DataSourceObject != null)
{
((ObjectDataSource)_gridView.DataSourceObject)
.Updating += new ObjectDataSourceMethodEventHandler(objectDataSource_Updating);
}
}
private static GridView _gridView;
private static void objectDataSource_Updating(object sender, ObjectDataSourceMethodEventArgs e)
{
var newObject = ((object)e.InputParameters[0]);
var oldObjects = ((ObjectDataSource)_gridView.DataSourceObject).Select().Cast<object>();
Type type = oldObjects.First().GetType();
object oldObject = null;
foreach (var obj in oldObjects)
{
if (type.GetProperty(_gridView.DataKeyNames.First()).GetValue(obj, null).ToString() ==
type.GetProperty(_gridView.DataKeyNames.First()).GetValue(newObject, null).ToString())
{
oldObject = obj;
break;
}
}
if (oldObject == null) return;
var dynamicColumns = _gridView.Columns.OfType<DynamicField>();
foreach (var property in type.GetProperties())
{
if (dynamicColumns.Where(c => c.DataField == property.Name).Count() == 0)
{
property.SetValue(newObject, property.GetValue(oldObject, null), null);
}
}
}
}
And in the Page_Init event of my page, I apply it to the GridView, like so:
protected void Page_Init()
{
GridView1.EnableLimitUpdateToGridViewColumns();
}
This is working well for me at the moment.
You could probably apply similar logic to other controls, e.g. ListView or DetailsView.
I'm currently scratching my head to think of a way this can be done in a rendering-agnostic manner - i.e. without having to know about the rendering control being used.
I hope this ends up as a normal feature of the GridView or ObjectDataSource control rather than having to hack it.

Resources