Automapper With NHibernate and DevExpress GridView - Caching - c#

My WebForms project uses an NHibernate class library as an OR mapper to our Oracle databases. The NHibernate library has been fully tested and is working without any issues.
Global.asax.cs:
void Application_Start(object sender, EventArgs e)
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
var cnnConfig = ""; //contains connection string information for NH
NHibernateClassLibrary.init(cnnConfig); //initializes NHibernate
var profileType = typeof(AutoMapper.Profile);
// Get an instance of each Profile in the executing assembly.
var profiles = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => profileType.IsAssignableFrom(t)
&& t.GetConstructor(Type.EmptyTypes) != null)
.Select(Activator.CreateInstance)
.Cast<Profile>();
// Initialize AutoMapper with each instance of the profiles found.
Mapper.Initialize(a => profiles.ForEach(a.AddProfile)); //ForEach is an extension method
}
ExtensionMethods.cs:
public static class ExtensionMethods
{
public static void ForEach<T>(this IEnumerable<T> enumerable,
Action<T> action)
{
foreach (T item in enumerable) { action(item); }
}
}
SampleProfile.cs:
namespace MyProjectName.AutomapperProfiles
{
public class EntityOneProfile : Profile
{
protected override void Configure()
{
base.Configure();
Mapper.CreateMap<NHibernateClassLibrary.Entities.EntityOne, EntityOnePoco>();
}
}
}
EntityOne.cs:
namespace NHibernateClassLibrary.Entities
{
public class EntityOne
{
public virtual string PropertyOne { get; set; }
public virtual string PropertyTwo { get; set; }
public virtual string PropertyThree { get; set; }
}
}
EntityOnePoco.cs:
namespace MyProjectName.GridEntities
{
public class EntityOnePoco
{
public string PropertyOne { get; set; }
public string PropertyTwo { get; set; }
public string PropertyThree { get; set; }
}
}
MyPage.aspx.cs:
namespace MyProjectName
{
public partial class MyPage : System.Web.UI.Page
{
//This gets us access to the NHibernate Class Library
IDATABASE DataBase = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IDATABASE>();
protected void Page_Load(object sender, EventArgs e)
{
var EntityOneRaw = DataBase.EntityOne.ToList();
var EntityOneObjects = EntityOneRaw.Select(q => AutoMapper.Mapper.Map<NHibernateClassLibrary.Entities.EntityOne, EntityOnePoco>(q)).ToList();
GridViewObject.DataSource = new BindingList<EntityOnePoco>(EntityOneObjects);
GridViewObject.DataBind();
}
protected void ButtonOne_Click(object sender, EventArgs e)
{
var Item = DataBase.EntityOne.First();
Item.PropertyTwo = "New Value";
DataBase.SaveChanges(); //NHibernate call to commit
}
}
}
MyPage.aspx:
<!--Other lines truncated-->
<dx:ASPxGridView ID="GridViewObject" runat="server" KeyFieldName="PropertyOne">
</dx:ASPxGridView>
<asp:Button ID="ButtonOne" runat="server" Text="Take Action" OnClick="ButtonOne_Click" />
The page_load method works fine. The grid will load with the database's current values, with the first entry's "PropertyTwo" equal to "Old Value" for example. If I press ButtonOne, the ButtonOne_Click method will fire and update the first entry in the EntityOne table appropriately. I've confirmed this directly in Oracle. Further, a breakpoint set right after this action completes shows that the NHibernateClassLibrary is appropriately fetching the new property. However, the GridView is still displaying "Old Value" until I stop IIS/Debugging and restart.
My first instinct is that caching is enabled somewhere, but I've confirmed NHibernate is not caching the old value. If EntityOne from the database is up to date, how do I force the AutoMapped EntityOnePoco to update at the same time? Am I missing something easy here?

The solution I found was to call DataBase.Clear(), essentially clearing the first-level NHibernate cache right before populating the EntityOneRaw object, as in the following example. My use-case benefits from first-level caching, so in my actual code, I only call the Clear() method as necessary.
namespace MyProjectName
{
public partial class MyPage : System.Web.UI.Page
{
//This gets us access to the NHibernate Class Library
IDATABASE DataBase = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IDATABASE>();
protected void Page_Load(object sender, EventArgs e)
{
DataBase.Clear(); //clear the first-level cache in NHibernaet
var EntityOneRaw = DataBase.EntityOne.ToList();
var EntityOneObjects = EntityOneRaw.Select(q => AutoMapper.Mapper.Map<NHibernateClassLibrary.Entities.EntityOne, EntityOnePoco>(q)).ToList();
GridViewObject.DataSource = new BindingList<EntityOnePoco>(EntityOneObjects);
GridViewObject.DataBind();
}
protected void ButtonOne_Click(object sender, EventArgs e)
{
var Item = DataBase.EntityOne.First();
Item.PropertyTwo = "New Value";
DataBase.SaveChanges(); //NHibernate call to commit
}
}
}

Related

c# MVC5 What is the right place to load menu items

I have a little problem, could you explain me what is the best practice to load menu items from DB using MVC5 and Entity Framework6. The menu and localization object must be loaded only once, and then just used from some globally available collection. They are not going to change alot after website launch, so I just goung to implement some Update() method and I'll call it when necessary...
Use child actions.
public class FooController : Controller
{
...
[ChildActionOnly]
public ActionResult SiteMenu()
{
// load menu items however you need to
return PartialView("_SiteMenu", menuModel);
}
}
/Views/Shared/_SiteMenu.cshtml
#model Namespace.To.MenuModel
<!-- render your menu here -->
/Views/Shared/_Layout.cshtml
<!-- wherever you want the menu to display -->
#Html.Action("SiteMenu", "Foo")
If you want to cache the result, so the menu doesn't have to be pulled from the DB each request, then you can use the OutputCache attribute on the child action like any other action.
As i have already sad, I have thinked about Global.asax
So there is currently 2 ways how I can do it with Global.asax:
Update using this method is bad idea, use the second one instead
public static ICollection<MenuItem> MenuItems {
get
{
if (Application["MenuItems"] != null)
return (ICollection<MenuItems>)Application["MenuItems"];
else
return new ICollection<MenuItems>();
}
set
{
Application["MenuItems"] = value;
}
}
private void LoadMenuItems()
{
MyContext mc = new MyContext();
this.MenuItems = ms.MenuItems.Include("SubCategories").AsNotTacking().where(x => x.SubCategory == null).ToArray();
}
protected void Application_Start(object sender, EventArgs e)
{
this.MenuItems = LoadMenuItems();
}
And another way (The second one):
public static ICollection<MenuItem> MenuItems { get; set; }
private void LoadMenuItems()
{
MyContext mc = new MyContext();
this.MenuItems = ms.MenuItems.Include("SubCategories").AsNotTacking().where(x => x.SubCategory == null).ToArray();
}
protected void Application_Start(object sender, EventArgs e)
{
this.MenuItems = LoadMenuItems();
}
And same thing for Localization...
Actually i dont know which one is better, need to run some tests.
Almost forgot:
All the things, are contained in the "CustomHttpApplication" class, which is derrived from "HttpApplication" class. and Global.asax shoul be derived from "CustomHttpApplication" class. This way the Global.asax file will be cean and readable, but the business logic will be located one level down...
So the complete code could look like so:
CustomHttpApplication.cs
public class CustomHttpApplication : HttpApplication
{
public static ICollection<MenuItem> MenuItems { get; set; }
private void LoadMenuItems()
{
MyContext mc = new MyContext();
this.MenuItems = ms.MenuItems.Include("SubCategories").AsNotTacking().where(x => x.SubCategory == null).ToArray();
}
}
Global.asax.cs
public class MvcApplication : CustomHttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
MenuItems = this.LoadMenuItems();
}
}
And one more edit, if you/me convert the "LoadMenuItems" method to be a "static" one, than you/me will be able to update MenuItems and/or Localization item collections when needed.

Avoid querying twice for the same thing ? (in page and in its master page)

I have a website with a page which looks like that :
public partial class MyPage : System.Web.UI.Page
{
private MyPageService service = new MyPageService();
private User user;
protected void Page_Load(object sender, EventArgs e)
{
user = service.CurrentUser;
if (user != null)
DoSomethingUsingUser();
}
}
My problem is the master page also needs to get back the current authenticated user in order to update its content (user money amount, new messages etc.), and perform some actions such as log out.
public partial class MyMasterPage : System.Web.UI.MasterPage
{
private User user;
protected void Page_Load(object sender, EventArgs e)
{
user = ...;
UpdatePage();
}
private void UpdateMoney()
{
if (user != null)
_Money.Text = "Money: " + user.Money;
}
private void UpdateNewMessages()
{
_NewMessage.Visible = (user != null) && user.HasNewMessages();
}
private void UpdatePage()
{
UpdateNewMessages();
UpdateMoney();
}
protected void _LogOut_Click(object sender, EventArgs e)
{
...
}
}
So my question is since "MyMasterPage" is "MyPage"'s master page, is there a clean way to share the current user object between the page and its master page, rather than query the database for it twice, once in page and once in master ?
Or should I query twice anyway ?
Thanks a lot !
In case it might be useful :
Here is the service used in MyPage :
public class MyPageService : CommonAuthenticatedService
{
public MyService()
{
}
...
SomeSpecificMethods();
...
# region Override
// Loads user resources specifically required for MyPage page
protected override IQueryable<User> LoadUserResources(DbSet<User> users)
{
return users
.Include(x => x.SomeProperty1)
.Include(x => x.SomeProperty2)
.Include(x => x.SomeProperty3)
...;
}
# endregion Override
}
And the common service, used in every service which needs authenticated user :
public abstract class CommonAuthenticatedService
{
public User CurrentUser { get; private set; }
protected UserRepo userRepo = new UserRepo();
public CommonAuthenticatedService()
{
SetCurrentUser();
}
protected abstract IQueryable<User> LoadPlayerResources(DbSet<User> users);
private void SetCurrentUser()
{
using (var uof = new UnitOfWork())
{
Guid? currentUserId = userRepo.GetCurrentId();
if (currentUserId.HasValue)
{
DbSet<User> users = userRepo.GetDbSet();
CurrentUser = LoadUsersResources(users)
.SingleOrDefault(e => (e.Id == (Guid)currentUserId));
}
}
}
}

ListBox forcing update of items

I created a ListBoxItem where I have a property Name and override ToString() to give back name. That works nicely when I add new items.
But now I need to force the ListBox to update the labels when I change the name of my ship. I thought Refresh or Update would do that but that doesn't work.
I might be missing something very easy here.
public class ShipListBoxItem
{
public ListBox Parent { get; set; }
public ShipType Ship { get; set; }
public ShipListBoxItem()
{
Ship = new ShipType();
}
public ShipListBoxItem(ShipType st)
{
Ship = st;
}
public override string ToString()
{
return Ship.Name;
}
public void UpdateListBox()
{
Parent.Refresh(); //My problem is here. Update doesn't work either.
}
public static ShipListBoxItem AddToListBox(ListBox lb, ShipType ship)
{
ShipListBoxItem li = new ShipListBoxItem(ship);
li.Parent = lb;
lb.Items.Add(li);
return li;
}
}
If you use a List<T> as the DataSource for the listbox it is pretty easy to have changes to items show up. It also means there is no real reason to have a special class for adding a ShipListBoxItem to a ListBox, your basic Ship class may work:
class ShipItem
{
public enum ShipTypes { BattleShip, Carrier, Destroyer, Submarine, Frigate };
public ShipTypes Ship { get; set; }
public string Name { get; set; }
public ShipItem(string n, ShipTypes st)
{
Name = n;
Ship = st;
}
public override string ToString()
{
return String.Format("{0}: {1}", Ship.ToString(), Name);
}
}
The form related stuff:
private void Form1_Load(object sender, EventArgs e)
{
// add some ships
Ships = new List<ShipItem>();
Ships.Add(new ShipItem("USS Missouri", ShipTypes.BattleShip));
Ships.Add(new ShipItem("USS Ronald Reagan", ShipTypes.Carrier));
lb.DataSource = Ships;
}
private void button1_Click(object sender, EventArgs e)
{
// change a ship name
lb.DataSource = null; // suspend binding
this.Ships[0].Name = "USS Iowa";
lb.DataSource = Ships; // rebind
lb.Refresh();
}
As an alternative, you can also tell the Listbox to use a specific property for the display using DisplayMember:
lb.DataSource = Ships;
lb.DisplayMember = "Name";
This would use the Name property in the listbox instead of the ToString method. If your list is changing a lot, use a BindingList instead. It will allow changes to the list show up in the ListBox as you add them without toggling the DataSource.
Try this
ListBox.RefreshItems()
msdn
EDIT: You can use an extended class like this:
public class FooLisBox : System.Windows.Forms.ListBox
{
public void RefreshAllItems()
{
RefreshItems();
}
}
private void button1_Click(object sender, EventArgs e)
{
(listBox1.Items[0] as ShipListBoxItem).Ship.Name = "AAAA";
listBox1.RefreshAllItems();
}
I managed to solve my problem.
Mostly, thanks Jose M.
I ran into a problem however. RefreshItems() triggers OnSelectedIndexChanged()
so my overridden class looks like this
public class MyListBox : ListBox
{
public bool DoEvents{ get; set; } // Made it public so in the future I can block event triggering externally
public MyListBox()
{
DoEvents = true;
}
public void RefreshAllItems()
{
SuspendLayout();
DoEvents = false;
base.RefreshItems(); // this triggers OnSelectedIndexChanged as it selects the selected item again
DoEvents = true;
ResumeLayout();
}
// I only use this event but you can add all events you need to block
protected override void OnSelectedIndexChanged(EventArgs e)
{
if (DoEvents)
base.OnSelectedIndexChanged(e);
}
}

Grid binded to EntityFramework Poco class via BindingSource is not automatically refreshing

This one is test project to show my question. (VS2012, WinForms, EntityFramework 5, XtraGrid 12.5)
Model created by EF PowerTools - Reverse Engineer CodeFirst tool.
In the timer1_tick event i'm changing mypoco.value property. I'm expecting that grid.cell shows this changes automatically but not. I also tried with textbox but the same.
if i uncomment BindingSource.ResetCurrentItem() in timer1_tick works expected but this is not my question. If i force to grid (or Textbox) to refresh everything is fine.
I expect that ef created proxy object notifies DbSet.Local (ObservableCollection) -> BindingList -> BindingSource -> Grid etc via interfaces,methots or inherit or i don't know... I'm asking about this notifying system and why not working? Or it is working but my expectation is wrong? (
Why this is not working as expected, Where i'm failing? Please also read notes in the code.
Thank you.
//FORM CODE
public partial class Form1 : Form
{
testContext context = new testContext();
MyPOCO mypoco;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
mypoco = context.MyPOCOes.Create();
// mypoco is created but not proxied currently. state = detached
// After adding it context proxy created and change tacking will be available
context.MyPOCOes.Add(mypoco);
// mypoco is in the memory but not saved to database. This is why using Local
myPOCOBindingSource.DataSource = context.MyPOCOes.Local.ToBindingList();
// Setup timer
timer1.Interval = 15 * 1000;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
// Change the property and then warn user about this event occured
// At this point mypoco is proxied
mypoco.Value = 99;
this.Text = "Timer Tick";
//myPOCOBindingSource.ResetCurrentItem();
}
}
// some code from Form1.Designer file
private System.Windows.Forms.BindingSource myPOCOBindingSource;
private void InitializeComponent()
{
this.myPOCOBindingSource = new System.Windows.Forms.BindingSource();
....
this.myPOCOGridControl.DataSource = this.myPOCOBindingSource;
}
//MYPOCO
public partial class MyPOCO
{
public int ID { get; set; }
public Nullable<int> Value { get; set; }
}
//MAPPING
public class MyPOCOMap : EntityTypeConfiguration<MyPOCO>
{
public MyPOCOMap()
{
// Primary Key
this.HasKey(t => t.ID);
// Table & Column Mappings
this.ToTable("MyPOCO");
this.Property(t => t.ID).HasColumnName("ID");
this.Property(t => t.Value).HasColumnName("Value");
}
}
//CONTEXT
public partial class testContext : DbContext
{
static testContext()
{
Database.SetInitializer<testContext>(null);
}
public testContext()
: base("Name=testContext")
{
}
public DbSet<MyPOCO> MyPOCOes { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new MyPOCOMap());
}
}
The proxy code of MyPoco is here: Nothing related on bindings (of course) ...
public sealed class MyPOCO_F874E881B0FD3EF02199CD96C63396B451E275C5116C5DFBE892C68733857FDE : MyPOCO, IEntityWithChangeTracker, IEntityWithRelationships
{
[NonSerialized]
private IEntityChangeTracker _changeTracker;
private static Func<object, object, bool> _compareByteArrays;
[NonSerialized, IgnoreDataMember, XmlIgnore, ScriptIgnore]
public object _entityWrapper;
private System.Data.Objects.DataClasses.RelationshipManager _relationshipManager;
private static Action<object> _resetFKSetterFlag;
private void EntityMemberChanged(string text1)
{
if (this._changeTracker != null)
{
this._changeTracker.EntityMemberChanged(text1);
}
}
private void EntityMemberChanging(string text1)
{
if (this._changeTracker != null)
{
this._changeTracker.EntityMemberChanging(text1);
}
}
public void SetChangeTracker(IEntityChangeTracker tracker1)
{
this._changeTracker = tracker1;
}
public override int ID
{
get
{
return base.ID;
}
set
{
if (base.ID != value)
{
try
{
this.EntityMemberChanging("ID");
base.ID = value;
this.EntityMemberChanged("ID");
}
finally
{
_resetFKSetterFlag(this);
}
}
}
}
public System.Data.Objects.DataClasses.RelationshipManager RelationshipManager
{
get
{
if (this._relationshipManager == null)
{
this._relationshipManager = System.Data.Objects.DataClasses.RelationshipManager.Create(this);
}
return this._relationshipManager;
}
}
public override int? Value
{
get
{
return base.Value;
}
set
{
try
{
this.EntityMemberChanging("Value");
base.Value = value;
this.EntityMemberChanged("Value");
}
finally
{
_resetFKSetterFlag(this);
}
}
}
}

How to properly implement MVC using C#.NET in Windows Forms Applications

I've been looking all over the web for example implementations of an MVC setup in .NET. I have found many examples but they all seem to differ in certain aspects. I have a book on Design Patterns that described that MVC was originated in Smalltalk so I read over several people discussing its implementation in that language. What follows is an example project I wrote utilizing what I gathered was a proper implementation but I've been confused by a few details.
One problem I run into is the proper order of the construction of the objects. Here is the impl in my Program.cs
Model mdl = new Model();
Controller ctrl = new Controller(mdl);
Application.Run(new Form1(ctrl, mdl));
The View:
Immediately I have a couple of issues I'm unsure of. First, if the view is supposed to only read data from the Model for updating, but contains a reference to it, what is stopping me from making the calls the controller does to the model from the view? Should a programmer just ignore the fact that they are exposed to the models member functions? Another thought I had, was perhaps the event that informs the view the model is updated, would send some sort of state object for the view to update itself with.
public interface IView
{
double TopSpeed { get; }
double ZeroTo60 { get; }
int VehicleID { get; }
string VehicleName { get; }
}
/// <summary>
/// Assume the form has the following controls
/// A button with a click event OnSaveClicked
/// A combobox with a selected index changed event OnSelectedIndexChanged
/// A textbox that displays the vehicles top speed named mTextTopSpeed
/// A textbox that displays the vehicles zero to 60 time named mTextZeroTo60
/// </summary>
public partial class Form1 : Form, IView
{
private IController mController;
private IModel mModel;
public Form1(IController controller, IModel model)
{
InitializeComponent();
mController = controller;
mController.SetListener(this);
mModel = model;
mModel.ModelChanged += new ModelUpdated(mModel_ModelChanged);
}
void mModel_ModelChanged(object sender, EventArgs e)
{
mTextTopSpeed.Text = mModel.TopSpeed.ToString();
mTextZeroTo60.Text = mModel.ZeroTo60.ToString();
}
public double TopSpeed { get { return Double.Parse(mTextTopSpeed.Text); } }
public double ZeroTo60 { get { return Double.Parse(mTextZeroTo60.Text); } }
public int VehicleID { get { return (int)mComboVehicles.SelectedValue; } }
public string VehicleName { get { return mComboVehicles.SelectedText; } }
#region Form Events
private void OnFormLoad(object sender, EventArgs e)
{
mComboVehicles.ValueMember = "Key";
mComboVehicles.DisplayMember = "Value";
mComboVehicles.DataSource = new BindingSource(mModel.VehicleList, null);
}
private void OnSelectedIndexChanged(object sender, EventArgs e)
{
mController.OnSelectedVehicleChanged();
}
private void OnSaveClicked(object sender, EventArgs e)
{
mController.OnUpdateVehicle();
}
#endregion
}
The Controller:
My only real issue with the way I have implemented the controller is that it seems a bit odd to me that is possible to construct the controller without definitely having a view assigned to it. I could ignore the view entirely but that would mean I would pass parameters to the controller's functions for updating the model which seems to miss the point entirely.
public interface IController
{
void OnUpdateVehicle();
void OnSelectedVehicleChanged();
void SetListener(IView view);
}
class Controller : IController
{
private IModel mModel;
private IView mView = null;
public Controller(IModel model)
{
mModel = model;
}
public void OnUpdateVehicle()
{
if(mView == null)
return;
mModel.UpdateVehicle(mView.VehicleID, mView.TopSpeed, mView.ZeroTo60);
}
public void SetListener(IView view)
{
mView = view;
}
public void OnSelectedVehicleChanged()
{
if (mView == null)
return;
mModel.SelectVehicle(mView.VehicleID);
}
}
The Model:
In my form, I have a combobox that is a list of the vehicles given in my pseudo database. I feel as though my form should actually implement multiple Views / Models because of this. A view specific to listing the possible vehicles with a corresponding controller / model, and a view for displaying information about the selected vehicle with its own controller / model.
public delegate void ModelUpdated(object sender, EventArgs e);
public interface IModel
{
event ModelUpdated ModelChanged;
void UpdateVehicle(int id, double topSpeed, double zeroTo60);
void SelectVehicle(int id);
double TopSpeed { get; }
double ZeroTo60 { get; }
IDictionary<int, string> VehicleList { get; }
}
// class for the sake of a pseudo database object
class Vehicle
{
public int ID { get; set; }
public string Name { get; set; }
public double TopSpeed { get; set; }
public double ZeroTo60 { get; set; }
public Vehicle(int id, string name, double topSpeed, double zeroTo60)
{
ID = id;
Name = name;
TopSpeed = topSpeed;
ZeroTo60 = zeroTo60;
}
}
class Model : IModel
{
private List<Vehicle> mVehicles = new List<Vehicle>()
{
new Vehicle(1, "Civic", 120.0, 5.0),
new Vehicle(2, "Batmobile", 9000.0, 1.0),
new Vehicle(3, "Tricycle", 5.0, 0.0)
};
private Vehicle mCurrentVehicle;
public Model()
{
mCurrentVehicle = mVehicles[0];
}
public event ModelUpdated ModelChanged;
public void OnModelChanged()
{
if (ModelChanged != null)
{
ModelChanged(this, new EventArgs());
}
}
public double TopSpeed { get { return mCurrentVehicle.TopSpeed; } }
public double ZeroTo60 { get { return mCurrentVehicle.ZeroTo60; } }
public IDictionary<int, string> VehicleList
{
get
{
Dictionary<int, string> vDict = new Dictionary<int, string>();
foreach (Vehicle v in mVehicles)
{
vDict.Add(v.ID, v.Name);
}
return vDict as IDictionary<int, string>;
}
}
#region Pseudo Database Calls
public void SelectVehicle(int id)
{
foreach (Vehicle v in mVehicles)
{
if (v.ID == id)
{
mCurrentVehicle = v;
OnModelChanged(); // send notification to registered views
break;
}
}
}
public void UpdateVehicle(int id, double topSpeed, double zeroTo60)
{
foreach (Vehicle v in mVehicles)
{
if (v.ID == id)
{
mCurrentVehicle.TopSpeed = topSpeed;
mCurrentVehicle.ZeroTo60 = zeroTo60;
OnModelChanged(); // send notification to registered views
break;
}
}
}
#endregion
}
In Conclusion of this tl;dr, I guess what I'm looking for, is some guidance on whether or not what I'm doing here represents a true MVC implementation and maybe for someone to shed some light on the aforementioned concerns. Any advice would be greatly appreciated.
We'll it depends on what you want to do. You currently have an implementation of the Supervising Controller. If you wish to remove the model from the view (and any databinding), you can implement a Passive View pattern instead. See this article for more differences.
(source: microsoft.com)
And Martin Fowler is king (GUI Architectures).

Categories

Resources