differences viewer control in .NET - c#

I have a challenging question. My requirement is like i have a xml file which has values like
Name 0,20
age 21,4
This is like field names values will be there in the following position. I have 100 records like this in my xml file. I want to dynamically read this xml file which is the layout. and to compare two output files generated by two different companies. Output1 and Output2... where the values for Name at the position and age at the position will be there. I want to read the values and manually show the user that there is a differences in the two files at these areas.
Is there any dynamic viewer control available in .net, C# windows , wpf app to display these differences in two files?

this is not a control but a full file difference tool written in c#. Source code is available as well(CharityWare).
http://www.menees.com/
You can see the source code to see how the file difference is implemented.

One of several possible solutions that come to my mind is:
Use XPathNavigator to parse those 3, in practice, files and compare their content.
For visualization use WPF RichTextBox, were you can load complete formatted text and format/color part of it, which you can use for highlighting the differnces found.
WPF RichTextBox Sample1
WPF RichTextBox Sample2
You need to consider that the WPF TextBox is, basically, easy to use but also addicted to consume a lot of memory, so keep an eye on the memory consumption of your app.
There are, naturally other editors, that you can use, like Scintilla, but I think the story in this case become more complicated.
EDIT:
There could be another non programming solution, is just using WinMerge and run that program (which is free) with required parameters. So it will care about showing/highlighting the differences found between 2 different files.
Choice is up to you.

The existing DataGrid class in WPF will meet this need nicely if you design a class like...
public class Difference
{
public string PropertyName { get; set; }
public string File1Value { get; set; }
public string File2Value { get; set; }
}
This class would hold the differences. You would create an instance of this class each time you found a difference you wanted the user to see, and you would add each instance to a collection...
public ObservableCollection<Difference> Differences = new ObservableCollection<Difference>();
And this collection would be bound to the ItemsSource property of the DataGrid.
Using this approach, you would not need to create a new control or use a 3rd party control. If you wanted to tart up the column headers, you can use DataGridColumns and Templates to that end.

Related

What's the easiest way to create a managed visualiser in C#?

I have a background in C++ and recently I started working in C#.
I have written following pieces of code (in Visual Studio):
var list_Loads = database.GetData<Load>().ToList();
var test_list = list_Loads.Where(o => (o.Name.Substring(0, 3) == "123")).ToList();
When I run the program and I move my mouse over both lists, first I get the count, which is very useful, but when I ask for the entries, this is what I get:
0 : namespace.Load
1 : namespace.Load
2 : namespace.Load
...
Not very useful, as you can imagine :-)
So my question: how can I show the Name attributes of those objects?
I thought: no problem. I have a background in native visualisers, so it should be rather easy to turn this into useful information, but then it comes:
In order to alter the way that those objects are represented, there is the first proposal to add a [DebuggerDisplay] "tag" to the definition of that class in source code.
However, as those classes are part of a framework I'm just referring to, I don't have access to the source code and hence I can't modify this.
Then I found another solution, which comes down to: "Write an entire C# project, debug, test and install it and it might work" (see documentation on "Custom visualisers of data" on the Microsoft website).
I almost choked in my coffee: writing an entire project, just for altering the view of an object??? (While, in C++, you just create a simple .natvis file, mention the classname and some configuration, launch .nvload and that's it.
Does anybody know a simple way to alter the appearance of C# object, without needing to pass through the whole burden of creating an entire C# project?
By the way, when I try to load a natvis file in Visual Studio immediate window, this is what I get:
.nvload "C:\Temp_Folder\test.natvis"
error CS1525: Invalid expression term '.'
What am I doing wrong?
Thanks in advance
OP (my emphasis):
In order to alter the way that those objects are represented, there is the first proposal to add a [DebuggerDisplay] "tag" to the definition of that class in source code.
However, as those classes are part of a framework I'm just referring to, I don't have access to the source code and hence I can't modify this.
Does anybody know a simple way to alter the appearance of C# object, without needing to pass through the whole burden of creating an entire C# project?
If you just want to specify [DebuggerDisplay] on a type, you don't have to have access to the source code. You can make use of [assembly:DebuggerDisplay()] and control how a type appears in the debugger. The only downside is that [assembly:DebuggerDisplay()] naturally only affects the current assembly whose code your mouse is hovering over. If you wish to use the customised display in other assemblies that you own, then you must repeat the [assembly:DebuggerDisplay()] definition.
Here's an easy before-and-after example with DateTime. I picked DateTime because we generally don't have access to the source code and it has some interesting properties:
var items = new List<DateTime>
{
DateTime.Now.AddDays(-2),
DateTime.Now.AddDays(-1),
DateTime.Now
};
...which on my machine defaults to:
Maybe I'm fussy and I just want to see:
Day of the week and
Day of the year
...I can do that via:
using System.Diagnostics;
[assembly: DebuggerDisplay("{DayOfWeek} {DayOfYear}", Target = typeof(DateTime))]
...which results in:
Example:
namespace DebuggerDisplayTests
{
public class DebuggerDisplayTests
{
public DebuggerDisplayTests()
{
var items = new List<DateTime>
{
DateTime.Now.AddDays(-2),
DateTime.Now.AddDays(-1),
DateTime.Now
};
}
}
.
.
.
}
Overrides
[assembly:DebuggerDisplay()] can also be used as a means to override pre-existing [DebuggerDisplay] on a 3-rd party type. Don't like what style they have chosen? Is the type showing far too much information? Change it with [assembly:DebuggerDisplay()].

UWP/C# Advice with storing application user data?

I need a bit of advice/opinions on storing data.
Im looking at essentially storing user input data and then reference it on a frequent basis. I would like to avoid data base storage as this is all going to be referenced locally. Ive seen that you can do XML serialised objects etc and wanted to know what you think about data storage.
If i give you an idea of what im looking at doing in a step by step it may give a better idea of what im trying to achieve:
User loads the program
Program reads the storage file
Different controls such as GridView and text boxes displays specific parts of the document such as Names, Dates etc.
User can add to the file by entering data into different fields across the whole sheet.
User is free to save the file when required, can create new files when required and can open sheets at any point
All information needs to scale. i.e. user can add up to 50 dates, 30 names etc and each of these cannot interfere with another data field. All of this data for each specific type will be able to be referenced by the ui controls
Its a bit of a big task and i was looking at doing it all using XML. Im not sure if this is the best way to do it and wanted your opinions. Mainly due to the way the data can dynamically adjust all the time through user input.
Any input on this would be appreciated. I can provide images of what im trying to achieve if necessary.
I personally use Newtonsoft JSON for saving my user data. You can build all your classes as normal and then fairly easily integrate the JSON serialiser/deserialiser without too much hassle. There will be some exceptions that may require a custom serialiser, but it's not too difficult to make those, especially if you only need to interpret one small part and then can just pass the rest of the file off to the default serialiser.
This is a very quick example how you could store some key-value preferences for a number of users in a file.
using Newtonsoft.Json;
[JsonObject]
public class UserData {
[JsonProperty] //Add a JSON property "Username" which is a string
public string Username { get; set; }
//IEnumerable types are converted to/from arrays automatically by Newtonsoft
[JsonProperty("Options")] //Set the name in JSON file to "Options"
public Dictionary<string, string> Preferences { get; set; }
[JsonIgnore] //Excludes this property from the JSON output
public bool SaveRequired { get; set; } //Set true when a change is made, set false when saved
}
There are very similar libraries like this that do the exact same thing for XML, but I've not had much luck figuring them out and I'm usually on a very tight time scale when I just need something that I know works.
If you can find a decent XML library and understand how to use it correctly, I'd recommend XML over JSON due to its strictly structured nature, and you can include schema versions and aid with integration into other systems by providing a well written schema.

Dynamic localization of messages

I have made a simple localization of messages. All messages are stored in the static class Lng
public static partial class Lng
{
public static readonly string AppName = "My application";
public static class Category1
{
public static readonly string ConfirmDelete = "Are you sure want to delete?";
}
}
In code usage is as simple as referencing fields
MessageBox.Show(Lng.Category1.ConfirmDelete, ...
Then there is a manager, which does following:
language selection
load corresponding translation
updating fields via reflection
export currently selected language on application exit for an update (in case if default language is selected - to create first translation for any other language)
It's irrelevant of how language files looks likes, but here is a reflection part
TranslateLng("Lng.", typeof(Lng));
...
private static void TranslateLng(string parent, Type type)
{
foreach (Type nested in type.GetNestedTypes())
{
string child = string.Format("{0}{1}.", parent, nested.Name);
TranslateLng(child, nested);
foreach (var field in nested.GetFields())
{
string key = child + field.Name;
DefaultAdd(key, (string)field.GetValue(null)); // store value in default language dictionary (if not created yet)
field.SetValue(null, GetValue(key)); // get value for currently selected language
}
}
This system has one problem: all messages are defined in one class, which required manual management (deleting and updating messages when updating code which uses them).
And I was thinking to change manager to register strings dynamically and simplify usage to something like
MessageBox.Show(Lng.Text("Are you sure want to delete?"), ...
So that text is defined right where it used, duplicated text can be handled by manager and so on.
There are however 2 problems:
I will need a complete list of all messages at the end of application run to export complete list of messages (for currently selected language). What if some of Lng.Text() are never called at that run? Is there a way to register them as they are used in code (compile time?)? So that all calls will be registered somehow, even if peace of code is never used.
How to generate key. I could use CallerMemberName, but right key are more useful, as they are telling exact purpose. To example, Lng.Configuration.Appearance.CaptionText. I could call Lng.Text(key, message), but then I have to manage keys, ensure in their uniqueness, which doesn't appeals me.
I recently worked on a project with internationaliztion and we used Resources in con junction with the Sisulizer program with great success. Having the resources solves your key problem as you manually enter the key when you extract the resources. You also get great support from Resharper which makes the whole process a breeze.
Sisulizer is then used to extract resources as well as strings hard-coded in our Win Forms and WPF classes. It can export a CSV which you can give your translators and it also supports pseudo translation, which makes testing such apps very easy as well.

Making a simple database-like program with C#/WPF

I'm working on making a small independent game, and I've reached the point where I'm storing data in XML files, and I'd like to be allow the non-programmers on my team to edit them easily via a GUI, which I'd like to put together with WPF and C#.
I have plenty of experience with C#, but barely any with WPF.
The program would have the following class:
class Foo {
public string Name;
public int Age;
public Foo(string name, int age) {
Name = name;
Age = age;
}
}
And the "database" would just be a
public List<Foo> FooList = new List<Foo>();
What I'd like to make, simplified, is a window with a ListBox on the left side, with "add" and "delete" buttons beneath it (to add and delete items to and from the FooList). The ListBox should have all of the entries in FooList (displaying their Name). On the right side of the window should be a field for Name and Age, and probably some kind of "Save" button.
Now, I could hack this together myself, and I was just about to, when I learned about the existence of data binding. I have no idea how it works (other than that it seems to let you bind controls to variables or something), but it seems like it would make making this a lot easier, right?
I apologize in advance if this seems like too much of a "do everything for me"-type question. I barely know WPF at all, like I said earlier, but I can, for example, handle the serialization and file saving parts myself. I just have no clue how data binding works and how to implement it into my situation (assuming this is even what I want to do).
Thanks in advance!
Here's Microsoft's official WPF databinding tutorial. There's a lot here. And there are many similar tutorials all over the intertubes waiting for you just a google search away. http://msdn.microsoft.com/en-us/library/ms752347.aspx
Simple answer, use XML Notepad to edit XML. It's lightweight enough for non programmers.
http://www.microsoft.com/en-us/download/details.aspx?id=7973

Build C# dll from SQL table

I have a SQL-table with three columns: Id, English and Norwegian. Id is the primary key. In my application I have a flag (EN/NO) to decide which language to use for labels, buttons ++ in the GUI.
The application is now doing a select * everytime the application loads, and the application is looking up all required values at runtime. But instead of loading the whole dataset for every instance, i want to export these values and create a dll so i can store these values locally.
Is there any possibility of creating this in-code so the dll will renew itself with every build? Or do I have to run some external program to dynamically create ex. a .cs code to copy/paste into my class? (I need to be able to re-run the process because rows will be added every time there is a need for a new label/text)
I have so far thought out three solutions on how to structure my export, but no clue on how to export the data:
Preserve the state of the DataTable in a static context and provide help-methods to standardize the way of getting the values out.
Create a class containing each unique ID as method-name, and a parameter to decide which value to return:
public static class Names
{
public static string 12345(string language)
{
switch (language)
{
case "EN":
return "Hello";
case "NO":
return "Hei";
default:
return "Hello";
}
}
}
Create a class containing a searchable list for each language with ID as key and the value (as value)
Why don't you create different resource files for different languages and load the appropriate one depending you the settings. You can do this by using System.Resources.ResourceManager. This article here explains this in detail.
EDIT: Following SO post also discuss this in detail Best practice to make a multi language application in C#/WinForms?
No, i don't like the idea to put internationalization strings into a class library, Why you don't just use the .NET internationalization feature already built in in the framework ?
Resource files are the best solution, not class library for this kind of work ...

Categories