Is there a way to pass the DbSet<T> into the page? - c#

I have the window with the page. The page displays a data from the my database. Also, on the window the buttons are placed, whose contents is according to the tables names of the database. These buttons switchs the page's content.
For example, this is the btnUsers button's click event, which displays the "Users" table:
void btnUsers_Click(object sender, RoutedEventArgs e) {
this.FrameMain.Navigate(new pageTable(Context.ctx.Users, ...));
}
The pageTable is the my "generic" page, that receives the Users class. Here is its constructor, which doesn't works:
public pageTable(dynamic table, ...) {
InitializeComponent();
TableTemplate<dynamic>.Init(table, ...);
}
Here is the my generic class, that operates on the DbSet<T>:
static class TableTemplate<T> {
internal static void Init(T table) {
foreach (string f in Foo(table, ...) {
...
}
}
}
The Foo method just extracts the columns from the DbSet<T> table:
internal static string Foo<T>(T item, ...) {
...
}
The point is, that the application terminates when I try to get the data from the table, at the button's event, used this generic approach.
I noticed, that at the Foo method, during the debug, the T type is differs, depending on the way, with which I pass the DbSet<T>:
if I explicitly initialize a new class instance (for the test):
static class TableTemplate<T> {
internal static void Init(T table) {
foreach (string f in Foo(new Users(), ...) {
...
}
}
}
, then the T type is System.Data.Entity.DynamicProxies.Users_E006B3..., and the Foo method is works;
without the explicitly initialization the T type is System.Data.Entity.DbSet`1[Namespace.Users], and the Foo method isn't works.
Is there a possibility to pass the generic entity class into the page? I don't know if XAML has a generic classes support, to use the generic pageTable<T> page. It could be a solution, but I suppose there is a more neat way to pass the entity.

I found the solution, and it doesn't use the generic page.
Well, when I tried to print the table content, I discovered, that pass a structured query into the TableTemplate.Init(). I remember, that never used the dbContext.TableClass as a function argument before, always converting the TableClass into the list.
I confess, I don't understand the EntityFramework and didn't expect such a result. Generally, I used the object type and already forgot why used the dynamic type...
I decided to pass the DbSet<T>, converted to the list (and this, as I understand it, are the different thigns) into the page's constructor, instead of the DbSet<T>. But, because I doesn't use the general page, I converted the items of this list into the object:
void btnUsers_Click(object sender, RoutedEventArgs e) {
this.FrameMain.Navigate(new pageTable(Context.ctx.Users.ToList<object>()));
}
Now, the pageTable page's constructor is next:
public pageTable(List<object> table) {
InitializeComponent();
TableTemplate<object>.Init(table, ...);
}
And, the Init method of the TableTemplate class is next:
internal static void Init(List<T> tableList) {
if (tableList.Count > 0) {
foreach (string f in Foo(tableList[0], ...) {
...
}
}
}
I haven't figured out how to display only the table's columns names, if tableList is empty. Thus, in this case, for now the page displays the empty DataGrid without the columns names. Nevertheless, I am glad, that could do I wanted.
At last, I will say, that indirectly agree with Xerillio.

Related

How to properly declare class variables (CUIT Controls)

I am setting up Coded UI Tests for WPF application and I want to use code approach instead of record-and-generate-code approach. I'd like to use page objects trough code and I need to declare control (buttons, tabs, etc.) variables in page objects that would be used by multiple functions.
I tried declaring the variable in a class and adding properties in constructor (pendingButton1)
and creating function which returns the control and assigning to a variable in a class (pendingButton2) but neither worked.
It works when I declare the variable (or create the variable by function) within the function that I want to use the variable in (pendingButton3 and 4).
public partial class Press : Header
{
WpfToggleButton pendingButton1 = new WpfToggleButton(_wpfWindow);
WpfToggleButton pendingButton2 = Controls.Press.getPendingButton(_wpfWindow);
public Press(WpfWindow wpfWindow):base(wpfWindow)
{
this.pendingButton1.SearchProperties[WpfControl.PropertyNames.AutomationId] = "Tab1Button";
}
public void clickPendingButton() {
WpfToggleButton pendingButton3 = new WpfToggleButton(_wpfWindow);
pendingButton3.SearchProperties[WpfControl.PropertyNames.AutomationId] = "Tab1Button";
WpfToggleButton pendingButton4 = Controls.Press.getPendingButton(_wpfWindow);
Mouse.Click(pendingButton1); //UITestControlNotFoundException
Mouse.Click(pendingButton2); //UITestControlNotFoundException
Mouse.Click(pendingButton3); //This works
Mouse.Click(pendingButton4); //This works
}
}
I'd like to make it work when I declare the pendingButton outside clickPendingButton() function since it is used in multiple other functions.
The helper function Controls.getWpfButton() return just properties of the button, not "real" button. It has to be used in a constructor, then it can be used anywhere within the class. I wouldn't say its best practice but it works for me.
Press.cs
public partial class Press : SharedElements
{
private WpfButton pendingButton;
public Press(WpfWindow wpfWindow):base(wpfWindow)
{
pendingTab = Controls.getWpfButton(_wpfWindow, "Tab1Button");
}
public void clickPendingButton() {
Mouse.Click(pendingButton);
}
}
Controls.cs
internal static WpfButton getWpfButton(WpfWindow wpfWindow, string AutomationId)
{
WpfButton button = new WpfButton(wpfWindow);
button.SearchProperties[WpfControl.PropertyNames.AutomationId] = AutomationId;
return button;
}
What you want appears to be exactly the sort f code that the Coded UI record and generate tool generates. It creates many pieces of code that have a structure of the following style:
public WpfToggleButton PendingButton
{
get
{
if ((this.mPendingButton == null))
{
this.mPendingButton = new WpfToggleButton( ... as needed ...);
this.mPendingButton.SearchProperties[ ... as needed ...] = ... as needed ...;
}
return this.mPendingButton;
}
}
private WpfToggleButton mPendingButton;
This code declares the button as the class property PendingButton with a private supporting field that has an initial and default value of null. The first time that property is needed the get code executes the required search and saves the found control in the private field. That value is then returned in each subsequent usage of the property. Note that assigning null to the supporting field can be done to cause a new search, as demonstrated in this Q&A.

How to store a list of Cases from Switch Statement?

In my program I have a listbox that when the user double clicks an object it looks to a switch statement to see what event should occur. As the list begins getting larger I'm curious if there is a way to avoid having to maintain the list of objects in 2 places (once in a list to Add to the listbox, and once in the switch statement.
Is there a way to index/read/store the various Cases of my switch statement, then add them as objects to my listbox?
Example: (doesn't work, just a theory)
Switch (n)
ForEach (Case c in Cases)
{
arrayCases.Add(c);
}
listbox.Items.AddRange(arrayCases);
EDIT:
Going on the Dictionary recommendations I now have:
public void SetDictionary()
{
//add entries to the dictionary
dict["cat"] = new Action(Cat);
dict["dog"] = new Action(Dog);
//add each dictionary entry to the listbox.
foreach (string key in dict.Keys)
{
listboxTest.Items.Add(key);
}
}
//when an item in the listbox is double clicked
private void listboxTest_DoubleClick(object sender, EventArgs e)
{
testrun(listboxCases.SelectedItem.ToString());
}
public void testrun(string n)
{
//this is supposed to receive the item that was double clicked in the listbox, and run it's corresponding action as defined in the dictionary.
var action = dict[n] as Action action();
}
I believe that my code above is mostly correct and that I'm understanding it, however the action line:
var action = dict[n] as Action action();
Shows an error stating 'action' is expecting a ';'. Is my logic here accurate? If so, why is the action call incorrect?
Dictionary<string, Action> is the way to avoid. Dictionary.Keys becomes ListBox.Items.
switch(n) becomes
var action = dict[n] as Action
action();
I suggest to move your operations into separate classes. Create a base class for your operations like the following one. I added a field for the form because you probably have to interact with your form. You can also pass in other objects if required.
internal abstract class Operation
{
protected readonly MyForm form = null;
protected Operation(MyForm form)
{
this.form = form;
}
public abstract String DisplayName { get; }
internal abstract void Execute();
}
Then derive one class for each operation.
internal sealed class DoThis : Operation
{
internal DoThis(MyForm form) : base(form) { }
public override String DisplayName
{
get { return "Do this!"; }
}
internal override void Execute()
{
// Code to do this. You can use this.form to interact with
// your form from this operation.
}
}
internal sealed class DoSomethingElse : Operation
{
internal DoSomethingElse(MyForm form) : base(form) { }
public override String DisplayName
{
get { return "Do something else!"; }
}
internal override void Execute()
{
// Code to do something else.
}
}
Now you can add all your operations to the list box
this.lsitBox.Items.Add(new DoThis(this));
this.lsitBox.Items.Add(new DoSomethingElse(this));
and set the display member property.
this.listBox.DisplayMember = "DisplayName";
Finally execute the selected operation in the event handler.
((Operation)this.listBox.SelectedItem).Execute();
This pattern gives clean separation between all your operations and makes future extensions easy and clean. For example you could add a property CanExecute to all operations if you have to check if a operation is currently available. Or if you have to support localization it is easy to add logic for presenting the name of the operation in the current UI language.
Another scenario that is easily supported is if you have some code common to all operations for example logging, security checks, performance measuring and things like that.
internal abstract class Operation
{
protected readonly MyForm form = null;
protected Operation(MyForm form)
{
this.form = form;
}
public abstract String DisplayName { get; }
protected abstract void ExecuteCore();
internal void Execute()
{
Logger.Log("Executing operation " + this.DisplayName);
try
{
this.ExecuteCore();
Logger.Log("Executing operation " + this.DisplayName + " succeeded.");
}
catch (Exception exception)
{
Logger.Log("Executing operation " + this.DisplayName + " failed.", exception);
throw;
}
}
}
Note that you now have to override ExecuteCore() instead of Execute().
One final thought - using an interface IOperation instead or in combination with the abstract base class may be helpful, too. This removes the need that all operation inherit from the same base class because this might sometimes be inconvenient. But I omitted this to not overengineere this even more.
You can't* enumerate case of switch with normal code.
What you can do instead is to replace switch with map of "action name" to "action handler" and than you'll be able to reuse this map for list of action names listbox. See Tilak's answer for sample.
*) If you are really inquisitive you can enumerate choices of switch. C# code is transformed to IL and IL can be read with code. So you can get IL for a method, write (or get existing - Parser for C#) parser for IL and find implementation of switch inside the method, pick all cases. You can even go straight to C# source at build time - but it is even more involved than IL parsing.
Yes there is a way to do this by making a dictionary of lambdas.
void Main()
{
// set up your dictionary
Dictionary<string,Action> myList = new Dictionary<string,Action> {
{ "one", () => { Console.WriteLine("One function"); } },
{ "two", () => { Console.WriteLine("Two function"); }},
{ "three", () => { Console.WriteLine("Three function"); }}
};
// do a "switch" (that is invoke a function that corresponds to a name)
myList["one"]();
// loop the list of keys (that is get a list of all the names)
foreach (string key in myList.Keys)
Console.WriteLine(key);
}
the output of this program:
One function
one
two
three
Also note -- you can add to this "switch" dynamically like this (which is cool and something you can't do with a classical switch statement.)
myList.Add("four",() => { Console.WriteLine("Four function is dynamic"); });
It sounds to me like the number of cases in your switch are going to change a lot. If this is true, then you might want to consider using a mechanism other than a switch statement. Perhaps you want to do something like Alexi Levenkov suggests, and then iterate a list of the stored Action Names and execute the associated handler. This way you will avoid having to add the action name to the action map and then add it to the switch.

Dynamic Auto updating (to UI, Grid) binding list in C# Winform?

I'm not even sure if I'm doing this correctly. But basically I have a list of objects that are built out of a class/interface. From there, I am binding the list to a DataGridView that is on a Windows Form (C#)
Here the list is a Sync list which will auto update the UI, in this case DataGridView.
Every thing works fine now, but now i would like to have the List should have an dynamic object, that is the object will have by default two static property (ID, Name), and at run time user will select remaining properties. These should be bind to the data grid. Any update on the list should be auto reflected in the grid.
I am aware that, we can use dynamic objects, but i would like to know , how to approach for solution,
datagridview.DataSource = myData; // myData is AutoUpdateList<IPersonInfo>
Now IPersonInfo is the type of object, need to add dynamic properties for this type at runtime.
public class AutoUpdateList<T> : BindingList<T>
{
private ISynchronizeInvoke _SyncObject;
private Action<ListChangedEventArgs> _FireEventAction;
public AutoUpdateList()
: this(null)
{
}
public AutoUpdateList(ISynchronizeInvoke syncObject)
{
_SyncObject = syncObject;
_FireEventAction = FireEvent;
}
protected override void OnListChanged(ListChangedEventArgs args)
{
try
{
if (_SyncObject == null)
{
FireEvent(args);
}
else
{
_SyncObject.Invoke(_FireEventAction, new object[] { args });
}
}
catch (Exception)
{
// TODO: Log Here
}
}
private void FireEvent(ListChangedEventArgs args)
{
base.OnListChanged(args);
}
}
Could you help out on this?
I guess the best way for you is 'to simulate' the properties. I guess the best way would be the ITypedList implementing, the great example is here.
Once I faced similar issue. For my case I've taken this approach. This just might be helpful for you.
Also, there is a way (it's not about anything 'dynamic') to have a base class with fulls set of properties you gonna use. But it won't work if you don't have all properties before the runtime.

C# Dynamic Invoking

Good Day,
I have a situation where I'm using code that contains a class called ImportFileContext. The code looks like:
// One of 5 different types can be passed in
public AddImportData(CustomType ModelData)
{
// Depending on which 5 different types, the formatted type will change
FormattedType data = ConvertModelDataToFormattedData(ModelData);
using (var db = new ImportFileContext())
{
// Can this next line be made dynamic?
db.ImportFormattedData.Add(data);
db.SaveChanges();
}
}
Basically, a CustomType will always be passed in to the method. However, there are five different custom types that can be passed in. Depending on which 5 can be passed in, the data will be modified.
Use cases:
Custom Type passed in, format data to a specific format, then add that item to
List of the db instance.
Custom Type 2 passed in, format data to a specific format, then add that item to
List of the db instance.
Custom Type 3 passed in, format data to a specific format, then add that item to
List of the db instance.
So what I'm looking for is a way add an item to the List depending on the data type without having to write several different methods to test which type I'm receiving then adding the item. I know of the strategy pattern and I could use that, but what about adding an item to a list?
I'm really trying to avoid writing code that would look like:
// One of 5 different types can be passed in
public AddImportData(CustomType ModelData)
{
// Depending on which 5 different types, the formatted type will change
FormattedType data = ConvertModelDataToFormattedData(ModelData);
using (var db = new ImportFileContext())
{
if (typeof(ModelData) == "CustomType")
db.ImportFormattedData.Add(data);
elseif (typeof(ModelData) == "CustomType1")
db.ImportCsvData.Add(data);
elseif (typeof(ModelData) == "CustomType2")
db.ImportTabDelimetedData.Add(data);
db.SaveChanges();
}
}
TIA,
coson
I don't know how feasible this is for your application, but you can always add the specific behavior to the CustomType class and subclasses can implement it however they need to.
public class CustomType
{
public virtual void FormatAndWriteToDB(DataBase db);
}
And then sublasses override as needed
public class CustomType1 : CustomType
{
public override void FormatAndWriteToDB(DataBase db)
{
FormattedType data = ConvertModelDataToFormattedData(ModelData);
db.ImportCsvData.Add(data);
}
}
That would make your code very clean in the example method:
public AddImportData(CustomType ModelData)
{
ModelData.FormatAndWriteToDB(db);
db.SaveChanges();
}
Of course you can change this around a bit. For example, if the FormattedType call is common to all of them, you could leave that in the AddImportData method and pass it as an argument to the FormatAndWriteToDB method.
The advantage of this is future additions just require implementing the new subclass of CustomType and no modification is needed to AddImportData.
Sounds to me like you're looking for double-dispatch. You can do this with the Visitor Pattern--which is basically what David Mason detailed--where you decouple the algorithm from the data by putting logic (the visit) into the class that contains the data. That, of course works, but requires you to modify the class outside of the algorithm in order to visit.
I find this complex and it's really just there because statically typed object oriented languages don't normally do runtime overloading. Fortunately in C# 4 they introduced the dynamic keyword which allows use to implement double dispatch much easier--or at least in a way that looks more like method overloading. Which means you create the method overloads, assign the value to dynamic variable, then invoke the method. The method that gets call will be chosen at runtime based on the value. For example:
public static void AddImportData(CustomType ModelData)
{
FormattedType data = ConvertModelDataToFormattedData(ModelData);
using (var db = new ImportFileContext())
{
dynamic temp = ModelData;
ImportData(ModelData, data, db);
}
}
private static void ImportData(CustomType modelData, FormattedType data, ImportFileContext db)
{
db.ImportFormattedData.Add(data);
db.SaveChanges();
}
private static void ImportData(CustomType1 modelData, FormattedType data, ImportFileContext db)
{
db.ImportCsvData.Add(data);
db.SaveChanges();
}
private static void ImportData(CustomType1 modelData, FormattedType data, ImportFileContext db)
{
db.ImportTabDelimetedData.Add(data);
db.SaveChanges();
}
I have more details on my blog at: http://msmvps.com/blogs/peterritchie/archive/2010/05/24/using-the-dynamic-keyword-in-c-to-improve-object-orientation.aspx

C# Generic Type Parameter with a Conditional Statement

I'm working with an API in C# with some classes as follows. There are two message classes MessageA and MessageB and a number of field classes FieldA, FieldB, etc. The field classes all belong to a base class Field.
A message will contain various fields which can be accessed as
msgA.getField(FieldX field)
(copies the FieldX entry (if it exists) from msgA to field) and
msgB.set(FieldX field).
There's also
msgA.isSetField(FieldX field)
to make sure a message contains a field of type FieldX.
I need to write a method to take a MessageA and copy over some of fields to a MessageB. I have a working function now, but it has a whole bunch of statements like
FieldX fieldX = new FieldX();
if(msgA.isSetField(fieldX))
{
msgA.getField(fieldX);
msgB.set(fieldX);
}
This seems silly to me, so I'd like to write a separate method to do this. I'm new to C# and generic types though, so I'm not quite sure the best way to do it. After trying a number of things, I've written
private void SetMessageB<T>(MessageA msgA, MessageB msgB, Field field) where T : Field
{
var field_t = field as T;
if (field_t != null)
{
if (msgA.isSetField(field_t))
{
msgA.getField(field_t);
msgB.set(field_t);
}
}
}
But this doesn't work. Within the inner conditional statement, the type of field_t gets converted to int. It sort of makes sense why this would happen (i.e., these functions can't take any type as an argument, so the compiler can't be sure it will work every time). But I'm wondering if someone can point out a good way to solve the problem. Feel free to link me to MSDN articles or tutorials or whatnot. Thanks for any help.
It would only make sense to use generics here if your message object's methods were generic as well:
class Message
{
bool isSetField<TField>(TField field) where TField : Field { ... }
void getField<TField>(TField field) where TField : Field { ... }
void set<TField>(TField field) where TField : Field { ... }
}
Then your method can be truly generic:
private void SetMessageB<T>(Message msgA, Message msgB, T field) where T : Field
{
if (msgA.isSetField(field))
{
msgA.getField(field);
msgB.set(field);
}
}

Categories