Miguel A. Castro's Blog

# Wednesday, September 29, 2010

My good buddy, Wally McClure was just featured in an article for “Application Development Trends” on iPhone development using Mono-Touch.  Wally has been speaking on this around the country, and I was actually an audience member in CodeStock this year.  I gotta say, I found the topic informative an intriguing, since I fall into the very category that he targets, .NET devs with iPhones.

It’s definitely a topic worth talking about since it brings together to really great platforms.  The article is not a how-to, it’s an interview conducted by Michael Desmond (isn’t that one of the former Monkees?), but it’s a nice read.

Check out the article at http://adtmag.com/articles/2010/09/29/monotouch-qa-with-wallace-mcclure.aspx.

Wednesday, September 29, 2010 2:24:59 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] - - Follow me on Twitter

# Friday, September 24, 2010

One of my latest challenges involved the topic of WPF sizing.  I’m referring to the manipulation of control widths in relation to their parent widths.  Most books tell you that this happens automatically, but I’m here to say otherwise gentle reader.  Now, I am fully prepared to admit that I may have missed something so if you’re a WPF expert out there and you think there is a better way to do what I’m going to show you, please respond. 

So here is my situation:

I have a window (user control actually, but then almost everything is in most WPF applications).  My window defines a grid with two columns, each which will contain a user control of their own.  It looked something like this:

 

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="300" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <src:Control1 Grid.Column="0" x:Name="ctlControl1" DataContext="{Binding Path=Control1ViewModel}" />
    <src:Control2 Grid.Column="2" x:Name="ctlControl2" />
</Grid>

The user control called Control1 contains a ListView control which defined an ItemTemplate to construct the content structure of each item.  The effect I wanted was to show the data for each item in read-only mode and provide an “edit” icon on each item.  Pressing it would convert that item to editable textboxes.  I got that working fine by providing two Grids inside my data template, setting one of them invisible, then using commanding on the button icons to change the view-model state to switch the Visibility of each grid was bound – worked like a charm and is a really nice effect.

My problem was that both the TextBlock and TextBox controls in each item view sized to its contents, then the widest one became the width of the actual ListView that contained everything.  Originally, the column that contained this entire user control (defined above) was set to Auto, so of course it would widen to the width of the longest text control.  This totally sucked.

I added a splitter to the grid in the user control that contained the other two controls and the results at first were weird.  I took the recommendation of most books and added the GridSplitter to its own column (set to Auto width) at first.  This enabled me to resize the grid columns but by then, the content user control’s width was already set and it would not resize along with my resize-drag.  Dragging the splitter to the right, left the contents of the first column fixed, and dragging to the left basically didn’t work past the already fixed-width of the first column.  I fixed this by adding the GridSplitter as the last control on the same column as one of the controls, like this:

 

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="300" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <src:Control1Grid.Column="0" x:Name="ctlControl1" DataContext="{Binding Path=Control1ViewModel}" />
    <GridSplitter ResizeDirection="Columns" Grid.Column="0" Width="3" />
    <src:Control2 Grid.Column="2" x:Name="ctlControl2" />
</Grid>

 

Now when I drag the splitter, the columns follow along the resize in both directions; however the TextBlock and TextBox controls in my ListView remain sized to their contents and would not stretch in either direction.  This still totally sucked.

After playing around significantly with this, I discovered that the ListView itself was sizing and resizing dynamically as I dragged my splitter so I needed to get the contents of each item to size similarly.  The solution was to bind the Width of each of my TextBlock and TextBox items to the width of the ListView in which they were contained.  I gave the ListView control a name (I don’t normally name my controls since most of my work happens in the View-Model anyway), then set the Width property of the contained controls like this:

 

<ListView Name="lvw1" ItemsSource="{Binding}" DataContext="{Binding Path=VuewModelPropertyGoesHere}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid Visibility="{Binding Path=EditMode, Converter={StaticResource notEditModeVisibilityConverter}, Mode=OneWay}">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="25" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="25" />
                        <RowDefinition Height="10" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Path=Name}" TextWrapping="Wrap" HorizontalAlignment="Stretch"
Width="{Binding ElementName=lvw1, Path=ActualWidth}" Margin="0,0,5,0" /> <TextBlock Grid.Row="1" Grid.Column="0" Text="{Binding Path=Description}" TextWrapping="Wrap" HorizontalAlignment="Stretch"
Width="{Binding ElementName=lvw1, Path=ActualWidth}" Margin="0,0,5,0" /> . . . </Grid> <Grid Visibility="{Binding Path=EditMode, Converter={StaticResource editModeVisibilityConverter}, Mode=OneWay}"> <Grid.RowDefinitions> <RowDefinition Height="25" /> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> <RowDefinition Height="10" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <TextBox Grid.Row="0" Grid.Column="0" Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}"
Width="{Binding ElementName=lvw1, Path=ActualWidth, Mode=OneWay}" Margin="0,0,5,0" VerticalAlignment="Center" /> <TextBox Grid.Row="1" Grid.Column="0" Text="{Binding Path=Description, UpdateSourceTrigger=PropertyChanged}"
TextWrapping="Wrap" AcceptsReturn="True" MaxLines="3" MinLines="3" VerticalScrollBarVisibility="Auto"
Width="{Binding ElementName=lvw1, Path=ActualWidth, Mode=OneWay}" Margin="0,0,5,0" VerticalAlignment="Center" />

 

This totally fixed my problem… almost.  While the binding worked perfectly, the look I got left one little detail to be desired.  You see, now the width of the textboxes as equal to the width of the ListView.  This made their right edge disappear, and no margin and padding setting would fix it.

What I needed to do is set the width of the controls to slightly less than the width of the ListView; 10 pixels less to be exact.  Apparently in WPF, you either bind or you do not bind; not a combination of the two.  And you certainly cannot do mathematics in the XAML.  So what to do?

At this point, I had become quite comfortable with the idea of a type-converter so this is the first thing that sprung into my mind.  I created a type converter that I could use in this binding.  The job of the type converter would be to take the incoming width, and rather than convert it to another type, simply adjust by a certain amount and return that number.  And what amount you ask?  Well, the type converter gives you a “parameter’ argument than you can fill in the XAML, so the answer is: any amount I desire.

The end-result worked and looked great.  Here’s the type converter code:

 

public class WidthToParentConverter : IValueConverter
{
    object IValueConverter.Convert(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        double width = (double)value;
        double adjustment = Convert.ToDouble(parameter);

        return width + adjustment;
    }

    object IValueConverter.ConvertBack(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        double width = (double)value;
        double adjustment = Convert.ToDouble(parameter);

        return width - adjustment;
    }
}

 

And here’s the adjusted XAML for the textboxes:

 

<TextBox Grid.Row="0" Grid.Column="0" Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}"
Width="{Binding ElementName=lvw1, Path=ActualWidth, Converter={StaticResource widthToParentConverter}, ConverterParameter=-10, Mode=OneWay}"
Margin="0,0,5,0" VerticalAlignment="Center" /> <TextBox Grid.Row="1" Grid.Column="0" Text="{Binding Path=Description, UpdateSourceTrigger=PropertyChanged}"
TextWrapping="Wrap" AcceptsReturn="True" MaxLines="3" MinLines="3" VerticalScrollBarVisibility="Auto"
Width="{Binding ElementName=lvw1, Path=ActualWidth, Converter={StaticResource widthToParentConverter}, ConverterParameter=-10, Mode=OneWay}"
Margin="0,0,5,0" VerticalAlignment="Center" />

 

 

I struggled with this for a quite a bit, mainly because of inexperience, but now I know exactly what to do in this situation and I hope sharing it helps some of you as well.

 

Until Next Time…

Friday, September 24, 2010 4:38:46 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] - - Follow me on Twitter
Dev Stuff | WPF
# Tuesday, September 14, 2010

9-14-2010 12-19-18 AMFor those of you that have downloaded my Pipeline Framework (on the downloads section) as seen in my last DNR-TV episode, there seems to be a weird block being put on the app.config file when the code unzips.

This problem is being manifested as a constructor exception in the XAML of the primary window of the client project, though the problem is not really there.

Though I have no idea how to avoid this, the fix is easy.  Find the app.config file in the PipelineFramework.Client project, right-click on it and select properties.  In the lower-right corner, click on the “Unblock” button and that’s it.

 

Sorry for the inconvenience.  If anyone knows a way to avoid having to do this altogether, please let me know.

Tuesday, September 14, 2010 12:16:20 AM (Eastern Daylight Time, UTC-04:00)  #    Comments [1] - - Follow me on Twitter

# Sunday, September 05, 2010

Got your attention yet?  Well, truth be told, it doesn’t really have multiple inheritance; not in the true sense.  However, with a little creativity in technique, and provided your needs are not too deep, you can simulate a pseudo-multiple-inheritance scenario.  So let’s start by totally stating the obvious.

We have BaseClass1 and BaseClass2, each with methods that write out to the console a message identifying themselves.

 

public class BaseClass1
{
    public void BaseMethod1(string arg1, bool arg2)
    {
        Console.WriteLine(string.Format("BaseMethod1 in BaseClass1 called with arguments: {0} & {1}.", arg1, arg2.ToString()));
    }

    public void BaseMethod2(string arg1, string arg2)
    {
        Console.WriteLine(string.Format("BaseMethod2 in BaseCall1 called with arguments: {0} & {1}.", arg1, arg2));
    }
}

public class BaseClass2
{
    public void BaseMethod1(string arg1, bool arg2)
    {
        Console.WriteLine(string.Format("BaseMethod1 in BaseClass2 called with arguments: {0} & {1}.", arg1, arg2.ToString()));
    }

    public void BaseMethod2(string arg1, string arg2)
    {
        Console.WriteLine(string.Format("BaseMethod2 in BaseCall2 called with arguments: {0} & {1}.", arg1, arg2));
    }
}

 

Now we have a couple of other classes which have their own methods and each also inherits from one of the base classes.  We all know that .NET will limit the inheritance to only one class.

 

public class DerivedClass1 : BaseClass1
{
    public void DerivedMethod1()
    {
        Console.WriteLine("DerivedMethod1 in DerivedClass1 called.");
    }
}

public class DerivedClass2 : BaseClass2
{
    public void DerivedMethod1()
    {
        Console.WriteLine("DerivedMethod1 in DerivedClass2 called.");
    }
}

 

If I instantiate these two classes, I can call either their own methods or the ones declared in the base class, right? 

 

DerivedClass1 dc1 = new DerivedClass1();
dc1.BaseMethod1("hello", true);
dc1.BaseMethod2("hello", "world");
dc1.DerivedMethod1();

DerivedClass2 dc2 = new DerivedClass2();
dc2.BaseMethod1("hello", true);
dc2.BaseMethod2("hello", "world");
dc2.DerivedMethod1();

 

Have I insulted your intelligences enough by stating the obvious in about as boring fashion possible?  Well I did that for a reason.  See, my needs are to give the functionality provided  by both base classes to a derived class and still keep it apart in two separate entities; only my so-called entities won’t be classes this time, they’ll be extension methods.

Extension methods, introduced in .NET 3.5, allow me to add functionality in the for of methods to existing types.  This is a little like subclassing the type, but in a different way.  You can add extension methods to types that are sealed, and don’t accept subclassing.  You can also add them to classes that meet a certain contract or more specifically, implement a specific interface.  That’s the technique I’m gong to use now.

As you more than likely know, .NET types can only derive from a single type, but they can implement as many interfaces as you need.   So the firs thing I’m going to do is refactor my base classes so they are interfaces instead.  Yeah, I know, interfaces don’t offer implementation, just definition.  Don’t worry I’ll get to that.  What you’ll notice though is the simplicity of my two interfaces

 

public interface IBase1
{
}

public interface IBase2
{
}

 

By simplicity I mean, emptyness.  These interfaces are basically just marker interfaces and will contain no definitions for anything.   What they will do is offer an abstraction on which to define an extension, using extension methods.  Extension methods are defined as static methods first of all.  In fact, the way we code them is simply syntactic sugar for the actual static methods into which the language compiler will turn them.  The first argument of each static method will correspond to the type I want to “extend”, and is identified as such with the word this in front of it.

 

public static class Base1Extensions
{
    public static void Base1Method1(this IBase1 baseClass, string arg1, bool arg2)
    {
        Console.WriteLine(string.Format("BaseMethod1 from IBase1 called with arguments: {0} & {1}.", arg1, arg2.ToString()));
    }

    public static void Base1Method2(this IBase1 baseClass, string arg1, string arg2)
    {
        Console.WriteLine(string.Format("BaseMethod2 from IBase1 called with arguments: {0} & {1}.", arg1, arg2));
    }
}

public static class Base2Extensions
{
    public static void Base2Method1(this IBase2 baseClass, string arg1, bool arg2)
    {
        Console.WriteLine(string.Format("BaseMethod1 from IBase2 called with arguments: {0} & {1}.", arg1, arg2.ToString()));
    }

    public static void Base2Method2(this IBase2 baseClass, string arg1, string arg2)
    {
        Console.WriteLine(string.Format("BaseMethod2 from IBase2 called with arguments: {0} & {1}.", arg1, arg2));
    }
}

 

Notice that in these methods, the first argument is of the type of one of the two interfaces.  Extension methods don’t have to extend specific types, they can also extend classes that implement a certain interface or inherit from a certain base class.  In this case, the former.  Notice that the implementation for each of these four methods is identical to the implementations defined earlier in BaseClass1 and BaseClass2.  All four of these methods could have been placed into one static class, since the class does nothing more than provide housing for the methods.  But I chose to split them up to better mimic the original base-class scenario.

Now I can attach the functionality provided by these methods any class, simply by implementing the appropriate interface.

 

public class DerivedClass3 : IBase1, IBase2
{
    public void DerivedMethod1()
    {
        Console.WriteLine("DerivedMethod1 in DerivedClass3 called.");
    }
}

 

Now, DerivedClass3 can call any extension method designed to extend the IBase1 or IBase2 interfaces.

 

DerivedClass3 dc3 = new DerivedClass3();
dc3.Base1Method1("hello", true);
dc3.Base1Method2("hello", "world");
dc3.Base2Method1("hello", true);
dc3.Base2Method2("hello", "world");
dc3.DerivedMethod1();

 

This does have its limitations.  Unlike a true base-class scenario, the code in each extension method can only access members of the type it is extending.  And in this case, that type is an interface and an empty one at that.  So obviously, this technique is useful only when the implementation code you want is not going to need any outside dependencies, while methods in a true base class can depend on other members of that base class.  Another limitation is that extension methods can only be just that, methods.  This technique would not work if you’re looking to simulate property inheritance.

So there you have it, multiple inheritance in .NET – ok maybe not, but pretty cool huh?

 

Until next time…

Sunday, September 05, 2010 12:12:29 AM (Eastern Daylight Time, UTC-04:00)  #    Comments [3] - - Follow me on Twitter
Dev Stuff
# Friday, September 03, 2010

We’re running the WCF Firestarter event in Philadelphia on September 18th.  This event was extremely successful in NYC, and give the great community that Philly has, I expect nothing less than an awesome turnout here as well.

The speakers will be myself, Danielo Diaz (DE), and Bill Wolf.

Here’s the registration link:  http://www.eventbrite.com/event/834424787/estwbreg

Friday, September 03, 2010 11:53:38 AM (Eastern Daylight Time, UTC-04:00)  #    Comments [0] - - Follow me on Twitter

Search
Me & My Flair

Read all about me here.
Download my Resume here.

Check out where I am here.
 
Click on logos above for profiles.
Archive
<September 2010>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789
Statistics
Total Posts: 40
This Year: 0
This Month: 0
This Week: 0
Comments: 93