Rendering image in BandedGridColumn from MySQL Blob field - c#

I have a number of images stored in a Blob type field inside a MySQL InnoDB database along with other information pertaining to those images stored in another fields.
As you know the Banded Grid View distributed in DevExpress version 11.2, with the help of Banded Grid Columns, is capable of rendering several types of data, most notably images.
So far I'm able to create every control and load any kind of data required, including the images, using the common MySqlDataReader and DataSet approach, through the Grid Control DataSource property, that owns the BandedGridView.
However as you know, when you load a Blob field from MySQL you are returned a byte array with the content of the file, in this case the image in question.
I was hoping DevExpress would recognize the binary data and realize it was a image file, and automatically render the image in all the rows under the Column assigned to handle the database Image field, however it did not and now that I think of it, it was probably far fetched hope.
Instead of rendering the image, each row of the column shows a simple string output referencing what type of object the field contains. In this case since its a binary representation of a file, it outputs System.Byte[].
I've search the DevExpress documentation and generally on the web, nothing clear was found that could solve my problem. There is a example of my desired result packed along with DevExpress, the solution named "GridMainDemo" under the WinForms -> XtraGrid section. Once your running the demo, change into Alternate Views and into Banded Grid View, then just click on any row under the picture column, and you will see a clear example of my desired result.
Of course I've looked into the source of that demo, however I cannot say that clarification and explanation was a clear aim of the DevExpress team that built such demo, and unfortunately I didn't had much time to look at it deeply. However from what I've seen this demo differs from the point that the images are stored locally as files, and already properly reference in some sort of repository, which doesn't help much with my problem.
To finish my question, sorry for the long reading, just wanted to give a clear idea of what my aim is, what stands in the way, and how all things are set in order to find a way to reach my aim.
Now to cut a long story short. A simple example of how to load a image from a MySQL Blob field into a column in a Banded Grid View and have it rendered after load or when the user clicks the field cell, would be ideal and with it I would be able to understand and do the necessary code so that my View also renders my images.
My biggest thanks with this, really.
Note: Unfortunately, using local or even remote stored files is not
a option. The images must be kept within the confinements of the
database.

It wasn't so hard after all, and seems hope was well place and DevExpress did most of the work.
So, to help those who have a similar question, here is what you have to do, so you can have a certain column showing a image stored in a Blob type field.
Assuming you already loaded the data to your grid and it's being displayed correctly with the exception of the image of course.
First: You must declare a RepositoryItemImageEdit type object, that will simply implement a ImageEdit type control in the cell, which when trying to edit the cell value it will show your image, the goal of this question. If your goal differs on that point simply read the note after this answer afterwards.
Second: You must add the previously last declared object to your GridControl.RepositoryItems collection property. You can easily accomplish it using the Add method.
Third: Now you must define what type of control will be used to render the data for you Image column, for that you simple reference the BandedGridColumn.ColumnEdit property to be equal to the object you just added before.
Example
/* Create your columns, bands etc manually or
have it done automatically after loading the data.*/
...
// Load the data from the database to your gridControl
...
// Step one
RepositoryItemImageEdit imageControl = new RepositoryItemImageEdit();
// Step two
gridControl.RepositoryItems.Add(imageControl);
// Step three
/* view is the View assigned to your grid control
where your data and columns are being shown.*/
// Assuming your database blob field is named `Image`
view.Columns["Image"].ColumnEdit = imageControl;
If your data was loaded correctly and your columns assigned properly to their respective fields then this should render a small icon on each cell of your Image column and once your click or focus on it, a ImageEdit control will be rendered and show your image.
Note:
There are other controls besides ImageEdit capable of rendering images, for those others you will have to find
theirRepositoryItem based implementation.
Also, your Image column must be editable, otherwise this approach won't
work. Bare in mind that allowing edition at the column level will not work if it is denied at the View level through the OptionsBehavior.Editable property.
I will mark my answer as the correct one since no one else provided any insight on how to solve my problem, however you are welcome to post any other working approaches to this problem. Thank you.

Related

C# show data from database in label

I've got a program which is linked to a Microsoft Access database and what I want to do is to display data from a data column, for example, customerName from the table customerDetails into a label. The drag and drop feature from the data sources panel puts the data into text boxes by default however, I want mine in labels. I've looked around but I couldn't find anything directly referencing how to put data into different controls like labels so any help is appreciated!
One way is to change the default control type for your fields in Data Sources window. Since you are already using that method, simply go to Data Sources window, expand your table and select required field(s). Then select a different control type (Label in your case) from the list.

WPF window that looks like excel

I am new to WPF and c#, and I am trying trying to create an excel like table with a fixed number of columns and a varying number of rows according to the user's needs.People advise to use a datagrid, but I am very confused, some say that it is used mostly to display data source content (which is data contained in database if I understood). I read also about listviews, binding things to itemsource...etc. This is really a lot of information to work with! What I simply need is a way to create a table with fixed columns, and adding rows automatically when the user clicks on a button, that's it! No binding, or anything of this sort.But how to achieve that? Also, if you have good websites tutorials for working with datagrids, I would be very grateful (most of those that I found are too much complex, or don't explain well).
Thanks a lot!
You can create datatemplates that will style your data to look however you like - in this case an Excel row. Then you can display this data as the ItemsSource in an items control. Since you want the number of rows to vary based on some criteria, your data should be in an ObservableCollection. I'm not sure how you'd set-up the header, but I think you could style-up some containers and bind their width properties to the datatemplate controls.
If you wish to do more cell level customizations, then you can try Grid
http://www.syncfusion.com/products/user-interface-edition/wpf/grid/grid-control

How to bind ContentType field to another field in Orchard?

I am trying to add two ImageField to my custom type so that when i select a single image it saves two version of selected file (e.g: Full Size & Thumbnail) in my fields.here i need to bind my second field to first one for accomplishing this.is there any possibilities of doing this?
thanks in advance.
Yo can try jquery to complete your second form while you type in your first, or create an event on post that you can subscribe to in your save Action Method if you want to go server side only.
The image field is not going to do that for you, so instead of trying to hack it, you should modify the code for the field so that it has an option to create thumbnails of your images on the fly (it should not be two separate image fields). Once you're done, you could consider contributing your work.

How to approach data-binding a BindingList of Lists to a DataGridView in C#?

I'm writing a program that functions as an Excel-style dictionary. Basically, it allows the user to add rows, edit rows, search through them, and so on. I use it for storing and studying vocabulary for foreign languages.
I've gotten a version up and running that I'm quite happy with. It uses a BindingList as a data source for a DataGridView in order to track changes and record them back to the BindingList that I use to store all the vocabulary, and the list itself is made up of a custom class I named "Term", that has properties for "English Word", "Spanish Word", "Examples", ect. What it doesn't do is let the user customize the fields, and that's where my problem comes in. It's pretty much "hard-coded" in that even if I'm studying Spanish or French, the Term class is going to be using the property for "Kanji" from Japanese.
I want to be able to have the user type in what fields they want the dictionary to display and keep track of--basically, they should be able to rename and add/remove columns from the DataGridView. My first thought was to implement this as a List, which stores the names of the fields (and accordingly the number of them, by using the List's length). Then, I would have a Word class that has a List property, and each string in the list represents one of the fields. Then I create a BindingList of this Word class, which leaves me with a BindingList of Lists.
When I try to databind my List list to my DataGridView, the grid comes up empty--it apparently has no idea how I want the data to be displayed and I'm having great difficulty figuring out how to tell it to. I'm not even sure if my approach of having a List of Lists is a good way to implement customizable fields, but it's the best I could think of. In any event, can anyone recommend a way to approach this that lets me add the fields to the table, but also tracks changes and pastes them back to the original source? I need the grid to be used as an editing tool for the user to not only add new elements, but also change existing ones.
It's a personal project, but it's driving me a bit crazy. I was up until 5AM last night trying to figure it out and came up empty-handed. Thanks very much for reading!
I've read your post a couple of times. I'm not sure I understand completly. If I don't, please give some details and I'll try to help.
If I had to do a Excel-like DataGridView, I think I'd use an Array. I would create an array of, say, 256 by 256 and put it as DataSource. Then after the user edits, you read the whole DataGrid and rewrite if it differs from the array you originally had.
I think you might be interested in this class:
http://www.codeproject.com/KB/grid/DGVColumnSelector.aspx
It allows the user to dynamically display which columns are shown in the DataGridView

What's the best way for me to bind data to a DataGridView?

I'm quite new to C# (coming from a Java background) and I'm working on a Form to quickly manage different data (e.g. Users, Domains, Computers) along with providing utilities that use the data.
To avoid confusion the following is a summary of the example data structure;
<User>
<Name>joe</Name>
<Domain>europa</Domain>
</User>
<Domain>
<Name>europa<Name>
<Domain>
<Domain>
<Name>group</Name>
</Domain>
<Computer>
<Name>localhost</Name>
</Computer>
In my Form I have tab pages for each data, each containing a DataGridView (containing a column for each member) to allow for simple management. I'm using a single DataSet which reads the data from an XML file (using a schema) when the Form Load event is fired. After reading the data I am setting the tables as the DataSource of their respective DataGridView using the code;
userDataGridView.DataSource = dataSet.Tables["User"];
domainDataGridView.DataSource = dataSet.Tables["Domain"];
computerDataGridView.DataSource = dataSet.Tables["Computer"];
This is working properly for the Domain and Computer DataGridViews as they only have single text columns which are mapped to the Name properties. However, the Domain column of for the User DataGridView is a combo box and I need that to contain all the possible Domains (e.g. europa, group) as well as the selected Domain being bound to User.Domain (also, the User.Domain being initially selected).
My main question is how I achieve the above but I also have some additional questions hopefully someone can answer;
I'm assuming that changes made to a DataGridView are immediately persisted in the underlying XML file as I am reading it from the build's output directory. Is this correct or is additional configuration/process required?
During my attempts at getting this to work I tried to use a DataRelation as follows;
DataRelation dataRelation = new DataRelation("Domain users",
dataSet.Tables["Domain"].Columns["Domain"],
dataSet.Tables["User"].Columns["Domain"]);
dataSet.Relations.Add(dataRelation);
How exactly do DataRelations work and what effect do/can they have?
In case it helps you understand/explain I am using the SharpDevelop IDE for working on this application.
Thanks in advance.
As you have already found out, the DataGridView is very powerful and does most of the work in an automagically way. Unfortunately you run into problems if these defaults doesn't match your preferences (like using a ComboBox for a text property).
To get the DataGridViewComboBoxColumn into the proper place you can do this programmatically within your code or (if possible) do it with the designer (in Visual Studio don't know if SharpDevelop supports it).
Using the (Visual Studio) Designer
For this scenario it is necessary that the structure of the data is known at design time by providing a class holding all (or more) informations as simple properties (like a person class with properties name, age, etc.). If this is available you can add a BindingSource to your control and click in the properties window at the button next to the DataSource property. Select Add Project Data Source and select Object and select your desired object.
Now you have a binding source configured with a specific type of DataSource. Next select your DataGridView and change the DataSource property to the recently created binding source.
After this the DataGridView will automatically be populated with a column for each property. Now you can easily step into the Columns property and change the behaviour and type of each column as you like.
To connect your concrete data with the DataGridView just apply your table to the binding source.
Doing the same at runtime
If you have Visual Studio and followed the above steps you can afterwards easily take a look into the Designer.cs file to find how Visual Studio did all the stuff. There is nothing you can't do also manually. So if you need to just do it.
Simply create a DataGridViewComboBoxColumn, set the DataPropertyName and HeaderText and you've got a good starting point. Get the IndexOf() the column you want to replace, remove it and Insert() your freshly created column at the position you want.
Before the Grid can show some data (in the ComboBoxColumn) you need to provide a list with the possible values. For this purpose the comboBoxColumn has a DataSource property on itself where you can provide the desired values. With the simplest scenario you just provide an ICollection<string>, but you can also give something more complex like List<KeyValuePair<Enum, string>>. If that's the case you should also set the properties ValueMember and DisplayMember to tell the ComboBox which properties of the objects should be used to populate the list.
Maybe with these informations given you should take a look at the MSDN article about the DataGridViewComboBoxColumn and study the example. This should give you some additional hints on how to set it up properly.

Categories