|
Thank-you for the reply.
For the purpose of having the DataGrid events exist within the MyDataGrid object rather than my main window. Would this be a bad approach?
|
|
|
|
|
If it is just one dataGrid used one time then generally speaking inheritance is not the best way to approach this. Although it is not the only way by any means to work with WPF, the MVVM design is very popular. If you have a set of requirements of what you are looking for your grid to do I will take a look and see if i can provide you with some sample code to get you started. One of the general principles of MVVM is seperating any code that involves your Data from the User Interface, using MVVM i find that it is quite rare that i am using EventHandlers for UI components.
If you are just looking to seperate out your event handlers you could do something like this:
public class MyWindow:Window
{
private MyDataCollection _gridData;
public MyWindow()
{
InitializeComponent();
_gridData = new MyDataCollection();
DataGrid1.RowAdded += _gridData.DataRowAdded;
}
}
public class MyDataCollection
{
public void DataRowAdded(object sender, EventArgs e)
{
}
}
I'm not saying the above code would be the right solution but you would not be inheriting a control you proabably don't need to if you are just aiming to seperate your Event Handling Code from your Window Code.
|
|
|
|
|
Sorry for the late reply. I was away from home the last 3 days.
Yes, I was thinking on the line of something like this.
For the moment, until I study recommended practices and patterns, this is not important.
There is one item that is bothering me though.
Why is it that when a given grid row is selected via code, the background is not highlighted in the same manner as when selecting the row via a mouse click.
For instance:
dataGrid1.SelectedIndex = 0;
The background row is highlighted in a light-grey color.
But clicking the row, the row is highlighted in blue.
I've determined this is a focus issue. If the grid is forced to have the focus, the row is highlighted blue. If it loses focus, it changes to grey.
In my particular case, it would be great to maintain the blue background on the row even if focus is lost. What would be the best way to do this?
modified 6-Aug-12 15:20pm.
|
|
|
|
|
try this.
Note this should be added inside the following xaml node:
<DataGrid>
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<Style.Triggers>
</Style>
</DataGrid.Resources>
</DataGrid>
|
|
|
|
|
I placed a trigger on property IsSelected.
Works fine.
Thank-you.
|
|
|
|
|
Ed,
Would you be able to provide some guidance to this problem:
I have a DataGrid which is bound to a DataTable.
Relevant XAML & code ('<' intentionally left off at start of each line):
DataGrid Name="dataGrid1" IsReadOnly="True" ItemsSource="{Binding}"
DataGrid.Columns>
DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" />
DataGridTextColumn Header="Path" Binding="{Binding Path=Path}" />
/DataGrid.Columns>
dataGrid1.DataContext = gridData.dt; // this is a DataTable with 3 columns.
The 3rd dt column is not shown on the grid.
The data table is sorted on the first column and contents are displayed.
The user can sort on either of Name or Path columns/headings by clicking on them.
My question, what is the best approach to update the grid data upon a user sorting on one of the columns? (This requires sorting the DataTable once again on the proper column)
This is what I have observed:
1. Adding a Click event handler on DataGridColumnHeader does fire the event.
I have observed that the value of columnHeader.SortDirection (in sender) is the
CURRENT value, not the target value. Is it correct to say that a given column
sort order goes through these phases:
null --> ascending
descending --> ascending
ascending to descending
I.E. By knowing the current state, the next state is determinable.
2. I can place a trigger in the DataGridColumnHeader's SortDirection property looking for Ascendiing/Descending/null but then what? Can I execute code against this?
If so, can you show me a code fragment.
Your thought on the above 2 approaches.
Furthermore, what is the proper way of solving this issue in your opinion?
Thank-you.
|
|
|
|
|
I'm afraid i have no experience with sorting on Grids, for most grids in the applications i work on we use a paid for grid component that handles the sorting for us. I'll have a quick look to see if i can figure out what you are after but i'd recommend you create a new post in the WPF forum with this question.
|
|
|
|
|
Ok had a little look at this, have you tried the following
<DataGrid Name="dataGrid1" IsReadOnly="True" ItemsSource="{Binding}" CanUserSortColumns="True">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" />
<DataGridTextColumn Header="Path" Binding="{Binding Path=Path}" />
</DataGrid.Columns>
</DataGrid>
For me adding the CanUserSortColumns="True" to the grid properties was enough to get sorting working, unless you need something more than visual sorting this should work for you.
|
|
|
|
|
Ed,
This sorts the columns visually but the DataTable data bound to the grid is not sorted.
Thank-you for your reply, I'll open a new subject.
|
|
|
|
|
I am trying to get a COM component properties. VS2010 shows the Dynamic Properties, but I can not figure out how to get them. Reflection always gives me an empty array of properties.
Can somebody help me?
thanks.
Bob Jiang
|
|
|
|
|
Try using a tool like OLE Viewer to view the COM file.
|
|
|
|
|
This is a fairly complex topic. You might want to read this[^] article to get some understanding of how to do it.
|
|
|
|
|
Thanks a lot, Pete!
I am going through the article right now, and am pretty sure it can solve my problem.
Bob Jiang
|
|
|
|
|
No problem. The concepts sure take me back.
|
|
|
|
|
Hi everyone,
i'm trying to decrypt some data that are sent me from an ASMX server. The server is not mine. The sysadmin provided me the decrypt function to decrypt the data:
public static string Decrypt(string strInputString, string strKeyString, string myIV)
{
if ((strInputString == null) || (strInputString.Length == 0))
{
return strInputString;
}
int num5;
int keySize = 0x100;
int blockSize = 0x100;
int length = keySize / 0x10;
if (strKeyString.Length > length)
{
strKeyString = strKeyString.Substring(0, length);
}
if (strKeyString.Length < length)
{
strKeyString = strKeyString.PadRight(length, '#');
}
Encoding.Unicode.GetBytes(strKeyString);
if (myIV.Length > length)
{
myIV = myIV.Substring(0, length);
}
if (myIV.Length < length)
{
myIV = myIV.PadRight(length, '#');
}
Encoding.Unicode.GetBytes(myIV);
byte[] bytes = Encoding.Unicode.GetBytes(strKeyString);
byte[] rgbIV = Encoding.Unicode.GetBytes(myIV);
RijndaelManaged managed = new RijndaelManaged
{
BlockSize = blockSize,
KeySize = keySize
};
MemoryStream stream = new MemoryStream();
for (int i = 0; i < strInputString.Length; i += 2)
{
stream.WriteByte(byte.Parse(strInputString.Substring(i, 2), NumberStyles.AllowHexSpecifier));
}
stream.Position = 0L;
MemoryStream stream2 = new MemoryStream();
CryptoStream stream3 = new CryptoStream(stream, managed.CreateDecryptor(bytes, rgbIV), CryptoStreamMode.Read);
while ((num5 = stream3.ReadByte()) != -1)
{
stream2.WriteByte((byte)num5);
}
stream3.Close();
stream2.Close();
stream.Close();
byte[] buffer3 = stream2.ToArray();
return Encoding.Unicode.GetString(buffer3);
}
I've created a Windows Form in C# that has four textbox, one for encrypted string, one for the key, one for the IV and the last for the decrypted result string.
When i receive this data from the server, I paste them in my form, and click on button associated to the decrypt function.
When the key is not at almost 16 character longer, it gets padded with "#" (pounds). Anytime the key doesn't need to be padded, the routine it's ok, and it prints the correct result string in the correct textbox. Anytime the key needs to be padded with "#", it shows me the exception "Padding in invalid and cannot be removed".
I've also tried to set PaddingMode to None, or other types, but it doesn't work. The sysadmin said that the problem is only mine. O_O
Does anyone can helps me ?
|
|
|
|
|
You usually get that error when the block size, key size, incorrect key, or initialization vector, or any combination thereof, don't match what was used to encrypt the data.
|
|
|
|
|
Yes, i know. But unfortunately i'm sure that the problem is the "#" character that the function use to pad the strings.
In fact, take a look to the encrypt function...
public static string Encrypt(string strInputString, string strKeyString, string myIV)
{
if ((strInputString == null) || (strInputString.Length == 0))
{
return strInputString;
}
int num4;
int keySize = 0x100;
int blockSize = 0x100;
int length = keySize / 0x10;
if (strKeyString.Length > length)
{
strKeyString = strKeyString.Substring(0, length);
}
if (strKeyString.Length < length)
{
strKeyString = strKeyString.PadRight(length, '#');
}
Encoding.Unicode.GetBytes(strKeyString);
if (myIV.Length > length)
{
myIV = myIV.Substring(0, length);
}
if (myIV.Length < length)
{
myIV = myIV.PadRight(length, '#');
}
Encoding.Unicode.GetBytes(myIV);
byte[] bytes = Encoding.Unicode.GetBytes(strKeyString);
byte[] rgbIV = Encoding.Unicode.GetBytes(myIV);
string str = "";
RijndaelManaged managed = new RijndaelManaged
{
BlockSize = blockSize,
KeySize = keySize
};
MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(strInputString));
MemoryStream stream2 = new MemoryStream();
CryptoStream stream3 = new CryptoStream(stream2, managed.CreateEncryptor(bytes, rgbIV), CryptoStreamMode.Write);
while ((num4 = stream.ReadByte()) != -1)
{
stream3.WriteByte((byte)num4);
}
stream3.Close();
stream2.Close();
stream.Close();
foreach (byte num5 in stream2.ToArray())
{
str = str + num5.ToString("X2");
}
return str;
}
It's perfectly specular to the decrypt function. If the key length >= 16, it's all ok, it doesn't get padded and the algorithm is ok. If the key length < 16, it gets padded with "#", and shows the exception.
I don't understand how VS could interpret a "#" in its textbox in a different way i want.
|
|
|
|
|
Try changing the PaddingMode so that you have managed.PaddingMode = PaddingMode.None;
|
|
|
|
|
Yes, I tried it before. The exception goes away, but the result is not what I expect. As result I get a string with asian character, but i know that the result must be a comprehensible alphanumerical string.
|
|
|
|
|
The padding mode needs to be set on both sides of the encryption. The alternative is for you to pad your key with a different character. Why does it have to be #?
|
|
|
|
|
My answer to Dave K. in the last reply will responds to your question. Thank you so much.
|
|
|
|
|
You've got a ton of problems with this code.
First, The two lines where you have:
Encoding.Unicode.GetBytes(...);
are getting the bytes all right, but then completely ignoring the returned data and dropping it. These lines do absolutely nothing.
Next, the length of the IV in bytes must be the block size divided by 8, not the key size. This line:
int length = keysize / 0x10;
should be
int length = blockSize / 16;
Also, you're using the Unicode encoding to convert a string to bytes. This limits your key string to 16 caharacters (for a 256 bit block size) since Unicode will return 2 bytes for every character in your IV and key strings. You're cutting the maximum size of your source string in half by using it.
I'd also factor out the code that does the string trimming and conversion to bytes with the following. I think it's pretty obvious what it does and how you use it:
public static byte[] UnicodeConvertStringToVector(string source, int sizeInBits)
{
int maxStringLength = sizeInBits / (UnicodeEncoding.CharSize * 8);
if (source.Length > maxStringLength) {
source = source.Substring(0, maxStringLength);
} else if (source.Length < maxStringLength) {
source = source.PadRight(maxStringLength, "#");
}
return Encoding.Unicode.GetBytes(source);
}
And finally, from the point where you declare bytes and rgbIV , your code is just a freaking mess. It's no wonder it doesn't work correctly. I don't know what the hell you're doing in there, but it shouldn't be returning a string. It should be returning an array of bytes.
I'm probably shooting myself in the foot by posting this, but here's the "cleaned up" code for this part:
byte[] keyData = UnicodeConvertStringToVector(myKeyString, keySize);
byte[] ivData = UnicodeConvertStringToVector(myIV, length);
byte[] encryptedData = null;
using (MemoryStream outputStream = new MemoryStream())
{
using (CryptoStream cryptStream = new CryptoStream(outputStream, managed.CreateEncryptor(keyData, ivData), CryptoStreamMode.Write))
{
using (StreamWriter encryptStream = new StreamWriter(cryptStream))
{
encryptStream.Write(strInputString);
}
encryptedData = outputStream.ToArray;
}
}
return encryptedData;
Your code might make a bit more sense if you used meaningful variable names instead of the generic "stream1", "stream2" garbage. Also, nobody puts "str" on the front of their variable names anymore.
modified 1-Aug-12 11:24am.
|
|
|
|
|
Dear Dave,
please accept my apologies for not explaining before my situation.
That two functions are not mine. I'm developing an application that will be installed on a client that will communicates with an ASMX server. This application haft to do so much things, but one of these, is decrypting data received via SOAP from the ASMX server. Given that this server is not mine, its sys administrator sent me these two functions, in order to implement them in my software. So i can't control either the encrypt function (because the data are encrypted from the server, and it sends them already encrypted) or the server. The sysadmin said me that the data received via SOAP must be decrypted in this way, when i explained my problem to him, he just said "there are hundreds clients working with that function, so the problem is yours. Check your .NET Framework and VStudio installations".
This evening i will apply your suggestions on my code, and i'll check the result. In the meanwhile, thank you so much for your help.
|
|
|
|
|
If he gave you the decryption function and the correct keys, and it still doesn't work, the problem is entirely HIS, not yours. If the code he gave you doesn't work as he advertised, then HE needs to get you code that does work with his broken implementation.
This has nothing to do with the .NET or VS installations. This has everything to do with poorly written code.
|
|
|
|
|
Dave Kreskowiak wrote: If he gave you the decryption function and the correct keys, and it still doesn't work, the problem is entirely HIS, not yours.
Yes, I absolutely believe in your opinion. Unfortunately, he's working for the Government, he created the Web Service that i haft to query, and he makes the rules, so I can say him what you said me, but knowing his behavior, surely he will not accept my advices. In Italian Government there is not a Supervisor Authority which may act against bad IT technicians.
Seeing your culture, may I ask an information? I've not developed the C# soap client yet, so in order to test the most complex function of this client (the decrypt function), i'm requesting the data with a PHP SOAP Client. My PHP SOAP Client print the result of the SOAP request in a textarea, so i copy-and-paste my three values in three textboxes in a C# Windows Form Application (encrypted, key and IV), and print the result in another textbox.
It can be differences between receiving directly the data with a C# SOAP Client, and receiving them with a PHP SOAP Client? The clients (developed by others) that he compares to the mine, are done completely in C#. My client is able to decrypt only strings where their key doesn't need to be padded with "#", their clients decrypt indistinctly all the encrypted strings...
|
|
|
|
|