Multi-language report in C# - c#

I'm writing reporting application in C# (local reports). I've made report patterns (rdlc files) and now I'm trying to make them autotranslating due to localization of user. I've managed to make a single translation (translation of one field, but there are many of them) with resource file, but this requires parameter to every textbox I use in report :
ReportParameter p = new ReportParameter("Report1Parameter3", GlobalStrings.FieldText);
this.reportViewer1.LocalReport.SetParameters(p);
Is there any way to make it more "direct" than using additional parameter for every text field?

This has been the solution in my desktop application.
Let's say you have a separate resource file stored in the same folder of your application and named Resources.dll created with a resx file named Reports.resx with Public access
Step 1
Set permissions for local report (this should be repeated after every reset)
<YourReportViewer>.LocalReport.SetBasePermissionsForSandboxAppDomain(new PermissionSet(PermissionState.Unrestricted))
Step 2
In your rdlc report add following code (under report properties or manually edit rdlc file adding the code under <Report>/<Code> tag)
Private Shared Resources As Type = Reflection.Assembly.LoadFile(IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources.dll")).GetType("Resources.Reports")
Default Public ReadOnly Property Item(name As String) As String
Get
Return Resources.GetProperty(name, Reflection.BindingFlags.Static Or Reflection.BindingFlags.Public).GetValue(Nothing).ToString()
End Get
End Property
Step 3
In your report you can reference strings in resources using an expression like this:
=Code!<NameOfYourResource>

I think you should put all field to your dataset, and process translate before bind data for every user.

Related

Reading task enterprise custom field values from mpp file using mpxj

I'm trying to read task details from a mpp file using net.sf.mpxj library. However, when trying to read custom fields, I get a byte array which I do not know what to do with! It is not the exact value of the custom field from that specific task. Can anyone tell me what to do?
ProjectReader reader = new MPPReader();
ProjectFile project = reader.read(#"C:\EPM\test2.mpp");
foreach (net.sf.mpxj.Task task in project.Tasks)
{
var Value = task.GetFieldByAlias("My Custom Field Name");
}
The "Value" will be a byte array and I do not know how to get the real value from it.
UPDATED ANSWER:
As of MPXJ 10.7.0 you can retrieve correctly typed values for enterprise custom fields. You'll also find a CustomFieldDataType attribute as part of the CustomField class which indicates what type you'll be retrieving.
(One interesting "gotcha" is that if your MPP file contains an enterprise custom field which is based on a lookup table, i.e. the user can only select from a fixed set of values, the user-visible text is NOT stored in the MPP file. You'll only get back a GUID representing the value the user has selected. Microsoft Project itself has this same issue... if you open the MPP file when you're not connected to Project Server, these values will appears as blanks...)
ORIGINAL ANSWER:
The main problem is unfortunately that MPXJ doesn't currently offer the same level of support for Enterprise Custom Fields as it does for other fields. While it is able to identify Enterprise Custom Fields and the aliases they've been given, at the moment it is only able to read the raw bytes representing the field data.
Enterprise Custom Fields are not as commonly used as other field types so there hasn't been as much time invested in locating the definitions of these fields in the MPP file. The field definition will contain the type information necessary to convert from the raw bytes to the expected data type.
Improved support for Enterprise Custom Fields is on the "to do" list for MPXJ.

Set a permanent value of a variable without using a database

I don't know how to describe it thoroughly in the title, but I need to set a permanent value of a variable/flag once a process has return true and maybe set some flag in the program itself the value rather than saving it to database. And once that variable/flag has already have that value then the program won't run the process again and just use the value. Is it possible? I'm using VB.Net. I can't use the database because database can be overridden and change values by using query. Thanks in advance!
You can simply use binary/XML serialization in a file to save the state of that variable through your program. Every time you restart your app you can access the value from that file to get its current state.
You can look at this example - http://www.centerspace.net/examples/nmath/csharp/core/binary-serialization-example.php
Basically, you will not save the value in the database but in a file. Anyways you need to persist the value somewhere.
Some ways below
You did not specify if you are afraid that your application or another one could change the value
How I would do it
My ideas below
1)You could use an xml file for example and zip a copy of it with a strong password. Every time you update the first xml you will update also the encrypted zipped xml.You can use a FileSystemWatcher and capture any file change, so if something/someone has changed the file you just get a new copy from the zip
2)You can store the value in the DB and add a trigger to prevent delete/update
for example
-- delete trigger
CREATE TRIGGER Function_Value_Deleted
ON [dbo].[FunctionsValueTb]
AFTER DELETE
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS (
SELECT [Flag] FROM deleted
)
BEGIN
ROLLBACK;
RAISERROR ('Record deletion is not allowed...', 16, 1);
END
END
*You can use also use THROW rather than RAISERROR
**Do the same for the insert and update actions
***You can also store the value into a log table or send an email
I found myself in a situation quite similar to yours a couple of days ago.
In the end, I decided to use the settings functionaly provided by .NET: it is easy to use and maintain, and so far it has given me good results.
Yo can see here what I am talking about:
Best practice to save application settings in a Windows Forms Application
That thread refers to C# but is easily applicable for VB.NET: I just had to follow the same steps in order to add the Settings file:
Right click on the project in Solution Explorer, choose Properties.
Select the Settings tab, click on the hyperlink if settings doesn't
exist. Use the Settings tab to create application settings. Visual
Studio creates the files Settings.settings and
Settings.Designer.settings that contain the singleton class Settings
inherited from ApplicationSettingsBase
And then, from my code, I use the settings like this:
Dim lastExecDate As Date = My.Settings.LastSuccessfulExecution
lastExecDate = lastExecDate.AddDays(1)
// Perform my next execution and do other stuff
My.Settings.LastSuccessfulExecution = lastExecDate
My.Settings.Save()
Next time you retrieve the parameter LastSuccessfulExecution, it will have the updated value.
One more remark, as stated in the post that I linked above:
Note that you need to set the scope property of your settings. If you
select Application scope then Settings.Default.< your property > will
be read-only
Finally, I see that you are using this to store the expiration date of a product, so you don't want the user messing around with it. According to this post, the actual values of the parameters are stored in an Application Data user folder. It is somehow obfuscated since it is not that easy to find and besides it contains a hash on its name... I don't know if that is well hidden enough for you.
If you want the value only to exist in memory when the application is running then you can use the main thread of the application and use:
int slotData = randomGenerator.Next(1, 200);
//to set the data
Thread.SetData(Thread.GetNamedDataSlot("SomeDataKey"), slotData);
//to get the data
int newSlotData = (int)Thread.GetData(Thread.GetNamedDataSlot("SomeDataKey"));
Or you can use the Windows Registry if your app only runs on Windows, if not then you would have to write the value/object to a file and read it from there.

Convert string to number value

From my C# code-behind I send a string value to my dataset. The data table also contains a field string type, which is dragged and dropped into Crystal Reports.
Now I need to divide that (string) value by some number, but strings can't be divided. So I need to convert the string to a value first - but I can't. No matter how I try to convert it always shows 0 on the report.
I created a formula called Euro:
NumericText({MYVALUE}) then ToNumber({MYVALUE})
And accessed it from another formula, EuroNum:
(If NumericText({Total}) then ToNumber ({Total}))
Then I created another field lets say TotalEuro where I did this in forumla, but it's always showing 0:
Euro/1.95
I used this formula:
If NumericText({VALUE}) Then ToNumber({VALUE}) / 1.955
Everything seems fine with Crystal Reports but I had problem in Visual Studio.
Even if this file is set up to copy everytime ,file somehow not copy changes to debug folder. So I manually moved this file to debug folder and everything was fine.

Automatically inserting value from another table in lightswitch

I am creating a desktop, C# application in Lightswitch. I have a DB file with a table called Reports and another table called StatusList. There are going to be 3 options in StatusList table - Unresolved, In Progress and Resolved. The Report table has a couple of not important fields and a field "Status", which is supposed to hold one of the three values from StatusList table
Now, when the user will create a new Report, I need the application to automatically insert the "Unresolved" value as the "Status" without user being able to change it.
I have tried using this method
partial void Reports_Created()
{
this.Status = "Unresolved";
}
but it is not working. I guess it is because I am trying to assign a String value to the field which is populated from another table.
I am using Visual Studio 2013 and this is my first Lightswitch app as well.
Thank you in advance for any help.
It sounds like your trying to pass parameters between screens. Beth Massi does a good job explaining how to achieve that in this video. And here is another MSDN link to a similar question
Shouldn't your code before like:
This.report.status = "Unresolved"
I.e. The report entity is not referenced by "this" (that refers to the screen).

How to run a test many times with data read from .csv file (data driving)

I am trying to automate some testing for one of our web applications and I need to know how I can make my Coded UI project read data from a CSV file. Lets say I want to test a log in screen. My CSV file will contain a few user names and passwords. I want my Coded UI test to read these log in details and loop through them to run the test on each set of data.
The web has many tutorials on data driving Coded UI tests. The basic steps for data driving with a CSV file are as follows.
Create the CSV file.
Add the CSV file to the project.
Make sure the CSV file is deployed.
Add the CSV file as a data source for an individual test.
Read the CSV fields and use them in the test.
The detailed steps, with some variations, are explained below.
Visual Studio 2010 has a "data source wizard" that does some of these steps. Visual Studio versions 2012 and 2013 do not have the wizard and so all the steps have to be done manually.
Create the CSV file
One way is to create the file in a spreadsheet then save it as Comma Separated Values. Another way is to use a text editor and just write the file. I use a spreadsheet program for big data source files and a text editor for creating small files. Some editors add a byte order mark (BOM) at the start of a file, that will be added to the first field name of the CSV which appears to make the field unreadable. See this page for more about the BOM.
Add the CSV file to the project
Use the context menu in solution explorer, select Add -> Existing Item. Then browse to the required file. Note the file filter will probably need to be altered to be *.* or *.csv.
Make sure the CSV file is deployed
Open the properties panel for the CSV file from solution explorer. Set "Copy to output directory" to "Copy if newer" or to "Copy always". Some documents recommend "Copy if newer" but I prefer "Copy always" as occasionally a file was not copied as I expected. The difference between the two copy methods is a little disk space and a little time, but disks are normally big and the time to copy is normally small. Any savings are, in my opinion, far outweighed by being sure that the file will be copied correctly.
Add the CSV file as a data source for an individual test
Replace the [TestMethod] attribute with the correct data source line. This Microsoft blog shows the replacement code for several possible data source file types. For CSV use:
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV",
"|DataDirectory|\\data.csv", "data#csv",
DataAccessMethod.Sequential), DeploymentItem("data.csv"),
TestMethod]
Note that the file name occurs three times and one copy has a # rather than a .. I have not found any useful documentation about the different fields of the Datasource(...) attribute so cannot advise further on how to choose values for non-CSV data sources.
The |DataDirectory| part above is replaced by the directory where files are deployed when the tests run. The whole file name within the string quotes could be replaced by a full path name of a file, if required.
Read the CSV fields and use them in the test
The Coded UI record and generate tool creates classes with fields that hold values entered into text boxes or used in assertions. Each action method has a ...Params class and each assert method has an ...ExpectedValues class, where the ... is the method name. The default values of these fields are the values used when the test was recorded. The recorded values can be overwritten by an assignment before the action or assertion method is called. The fields of the current row of the data source are accessed from TestContext.DataRow[...].
Suppose a Coded UI test has an EnterValue method that writes text into two fields of the screen and it also has a CheckResult method that asserts one field. The test method might then be written as follows.
[DataSource...
TestMethod]
public void CodedUITestMethod1()
{
this.UIMap.EnterValueParams.UIItem0TextSendKeys = TestContext.DataRow["ValueOne"].ToString();
this.UIMap.EnterValueParams.UIItem1TextSendKeys = TestContext.DataRow["ValueTwo"].ToString();
this.UIMap.EnterValue();
this.UIMap.CheckResultExpectedValues.UIItem0TextDisplayText = TestContext.DataRow["Result"].ToString();
this.UIMap.CheckResult();
}
The ...Params and ...ExpectedValues classes allow the test to create values when the test runs. For example, if the EnterValue method also wanted to write tomorrow's date into a field we could add the following line before it is called:
this.UIMap.EnterValueParams.UIItem2TextSendKeys = DateTime.Now.AddDays(1).ToString("yyyy-MM-dd");
Add Data Source attribute in the Coded UI Test.
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "|DataDirectory|\\data.csv", "data#csv", DataAccessMethod.Sequential), DeploymentItem("data.csv"), TestMethod]
Note: This datasource driver determines cell type based on the data in the first data row. If you have a column that should be formatted as a string, but the first data row has a numer e.g.1234. The following rows will be returned as 0 if they are not empty.
Hope, this link may help you :
http://blogs.msdn.com/b/mathew_aniyan/archive/2009/03/17/data-driving-coded-ui-tests.aspx
You don't need to go into test view. Simply replace your [TestMethod] with the below script:
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "|DataDirectory|\\LoginInfo.csv", "Sheet$1", DataAccessMethod.Sequential), DeploymentItem("LoginInfo.csv"), TestMethod]
From there, change the LoginInfo.csv to the name of your .csv file. To reference your data just use:
// Username and Password are Column Headers
UIMap.LoginParams.UserNameTextBox = TestContext.DataRow["UserName"].ToString();
UIMap.LoginParams.PasswordTextBox = TestContext.DataRow["Password"].ToString();
UIMap.Login();
This will take the item in each column and use it sequentially in each test.

Categories

Resources