Saturday 6 August 2011

Battling with PDO

I’ve been having a lot of problems with error HY093, and having the wrong number of parameters.

There are some blogs around that imply that you can pass an object converted to an array to the execute function documented below.

 http://php.net/manual/en/pdostatement.execute.php

$query = $dbh->prepare(
"INSERT INTO `myTable` (ID, Val1, Val2) "
."VALUES(:ID, :Val1, :Val2)");
$query->execute((array) $crud);


This does appear to work, and seems to occasionally work when there are more fields in the object than are in the query. 

 

Generally though it does not work.  Instead bind explicitly like this.


$query->bindParam(":ID", $crud->ID);
$query->bindParam(":Val1", $crud->Val1);
$query->bindParam(":Val2", $crud->Val2);
However, the documentation above states an FALSE will be returned if you bind more parameters than specified.

Friday 5 August 2011

Json serialization and DateTime

Oh dear.  You don’t want to go there.

First, go here:

http://msdn.microsoft.com/en-us/library/bb412170.aspx

Good luck.

Silverlight 4 DataForm EditEnd(ing). Your current item is not current if you use AutoCommit=true.

Stumbled onto this strange one today.  My DataForm EditEnding and EditEnded events are being caught, and I’m using that to push my data across to my web server.

Unfortunately, the CurrentItem does not point to the item you are editing, as it has been moved onto the new item you’ve navigated to.  Strangely though, the CurrentIndex is still pointing to the correct index.

However, as everything seems to be in an inconsistent state, I’ve instead chosen to store the CurrentItem when BeginningEdit is raised.

How can I add/remove with a Silverlight 4 DataForm?

More hair pulling ensues, trying to figure out what to do to add or remove rows from the data form.

Again, after much googling, step 1 is to make the buttons visible, which you can do like this:

<toolkit:DataForm CommandButtonsVisibility="All" 
ItemsSource="{Binding Gigs}" ... />

where Gigs is an ObservableCollection of my items.



Alas, that now shows the add/delete buttons, but unfortunately, the add button in my case still wasn’t enabled.


The cause?  For the add button to work, you must ensure that your item has a constructor that takes no parameters!

Thursday 4 August 2011

Binding a DataGrid Column to an ComboBox containing an enumeration

In WPF it’s quite easy to bind a combo box to an enumerated type.  Unfortunately in Silverlight, I found myself in for a world of pain.

In the end, I found the following solution (starting off from this blog)

First, we need to collect up all of the names in our enumerated type.  We due this by using Reflection.

public static ObservableCollection<T> walkEnum<T>()
{
Type t = typeof(T);

var v = new ObservableCollection<T>() ;
// Retrieve the info for the type (it'd be nice to use Enum.GetNames here but alas, we're stuck with this)
FieldInfo[] infos;
infos = t.GetFields(BindingFlags.Public | BindingFlags.Static);

// Add each proper enum value to the collection
foreach (FieldInfo fi in infos)
{
v.Add((T)Enum.Parse(t, fi.Name, true));
}

return v;
}


The static method above returns an observable collection of all of the individual public named values in an enumerated type, by walking over the fields, getting the name, and then parsing the name back into the enumerated type itself.


Next we need to define our editing template in our DataGrid.


<sdk:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox SelectedItem="{Binding Instrument, Mode=TwoWay}"
ItemsSource="{Binding Source={StaticResource Sections}}"/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellEditingTemplate>


The key here is the binding to a StaticResource.  I initially tried to bind to a property of an element name, but because this is in a data template, the LogicalTree is yet available, and the element fails to bind.


Finally, there’s the matter of setting the static resource.  Rather than create a new object so I could construct it in XAML, I decided it would be better to dynamically add the object to the StaticResources in the code behind.  Here’s how I did it:


First, we define our enum.


[DataContract(Name = "Section", Namespace = "YourNamespaceHere")]
public enum Section
{
[EnumMember] Conductor = 1,
[EnumMember] Soprano,
[EnumMember] TuttiCornets,
[EnumMember] RepianoCornets
// ...
}






Notice that the enum starts with 1.  That’s something else I found out along the way on this project.  MySQL database enums reserve 0 as an undefined value, but that will have to wait for another blog entry.


Next, we need to create our collection to be used as the ItemsSource as the first line of our objects constructor.


this.Resources.Add("Sections", walkEnum<Section>());

 

And there you have it.  A combo box bound to enums in a Silverlight 4 DataGrid.

Customizing the Silverlight 4 DataForm

I’ve been working on a web based project in my spare time, and was trying to edit an object downloaded from my web server.

In the end, I eventually found that the DataForm from the Silverlight toolkit should make it easy to display the data in my object.  So, Initially, I let it wire up to my object like this:

<toolkit:DataForm Grid.Column="1"          
Name="dataForm1" ItemsSource="{Binding Gigs}"
CurrentItem="{Binding ElementName=dataGridGigs,
Path=SelectedItem, Mode=TwoWay}"
/>




 

Unfortunately, the Gigs object had a member declared like this:

 

public DateTime StartTime { get; set; }


which generated a default field editor of a date picker, which didn’t allow me to set the time!  Unfortunately, the time is just as important as the date in my application.


I searched around the web for awhile to find out how to customize the DataForm, but unfortunately most of the references were for Silverlight 3, and there have been many breaking changes since then.


So, I dug out my copy of Silverlight 4 unleashed and found the Section in Chapter 8, on page 212 that specifies how to define the fields manually.  Alas, the description warns off the user, saying that the validation summary won’t appear.


Sure enough, the code included didn’t show the validation summary as advertised.


Nevertheless, I persisted.


<toolkit:DataForm Grid.Column="1"  
Name="dataForm1" AutoGenerateFields="False"
ItemsSource="{Binding Gigs}"
CurrentItem="{Binding ElementName=dataGridGigs,
Path=SelectedItem, Mode=TwoWay}"
>
<toolkit:DataForm.EditTemplate>
<DataTemplate>
<StackPanel>
<!-- ... -->
<toolkit:DataField Label="StartTime">
<TextBox Text="{Binding Path=StartTime,

Mode=TwoWay}"
/>
</toolkit:DataField>
</StackPanel>
</DataTemplate>
</toolkit:DataForm.EditTemplate>
</toolkit:DataForm>




Suddenly, not only did validation appear, but my data was also updated in the object.


The key is setting the TextBox databinding to be TwoWay!