Working Topics

Hello again (again again again…..)…it is I…the brain that dwells within Toffer’s very spacious cranium.

I’m not through with this blog yet…not by a longshot. ¬†ūüôā ¬†Going forward I’ll be using¬†this post to keep track of the topics I’m currently blogging about or plan to blog about…so I’ll be continuously editing this post as I go.

As of this very second, here are the topics I have in my brain…Keep tuned and as always, Enjoy! ¬†ūüôā

Current Topics:

These are topics that I’m currently blogging about and actively updating the posts because I’m not 100% finished yet. ¬†Once a post is 100% complete I’ll move it off this list and it’ll just be it’s own thing at that point.

  • Evolvinator – What the hell? ¬†Something new!?! ¬†Yup. ¬†I’m getting my head wrapped around something new and I intend to start posting about it. ¬†It’s stupid and probably only interesting to me…but something I said was helpful to someone once, so what the hell. ¬†Evolvinator is going to be a little project app I’m going to let “evolve” to teach myself things about evolution. ¬†I’m going to try and keep maticulous track of it’s progression so I can do an over-time sort of post-mordem sort of thing. ¬†Lets see if I can actually keep myself disciplined enough to do it. ¬†ūüėõ
  • Switching from using BackgroundWorker to using Task in a WPF app
  • Binding a Telerik Kendo Grid column that has a null value object when trying use a sub property for displaying the value
  • What’s this SignalR stuff anyway?
    • My work is having me do investigation into how to incorperate SignalR into what we do so I’ve got a few samples to blog about here. ¬†Nifty stuff. ¬†I’m going to enjoy adding it into my superduper omega supreme wonder app.
  • http://www.telerik.com/forums/rebind-combobox-after-disable-enable-sequence#OXB3jC1RGkOfMCS1Z1FXiw
    • I bumped into this and it’s about enabling and disabling kendo comboboxes, but it pretty much applies to all kendo controls
  • Regex tricks
    • I’ve recently had to learn how to use regex queries…like a lot of them, so I’m going to post some of the tricks I used to get some of the data I was looking for in a given string.
    • I’ll also explain in length about how great the site www.regex101.com is. ¬†ūüôā

Retired Topics:

These are topics that I was thinking about digging into, but for one reason or another decided it wouldn’t be worth my time…the “back burner” so to speak…

  • Making a WPF app using python for code behind instead of C#
    • I did some work on this and got a project setup enough to actually create a page while using python code behind…I’d be willing to make a post about the experience if anyone had interest…but mostly what I found is that while it seems like a novel idea at first, it’s just easier to let C# do what it already does well with WPF and let python do what it’s good at instead of trying to marry them…so I’m not going to be doing any more investigation down this path.

 

Advertisements
Working Topics

Setting a Custom WPF ToolTip and how to keep it shown…

Ok, so to be perfectly honest I was a little bored at work and decided to experiment with my super duper omega wonder app (now with kitchen sink features). ¬†My experiment was to put some ToolTip pop ups of historical data about whatever cell the mouse happened to bre hovering over…so I started whipping up a test app to figure out how to do that…and you the lucky reader can follow my journey. ¬†I should be charging for this, I know but we can chalk it up to my humanitarian contribution to our species for now. ¬†*drip drip drip of sarcasim*

Ok, so in our test app we need a WPF window with a basic generic grid on it. ¬†I’ve been using Telerik WPF controls, but everything I do in this post should work just as well with standard .NET WPF controls as well. ¬†Telerik isn’t doing anything special to ToolTips and AFAIK they just expose the underlying .NET stuff. ¬†Anyway, my examples will all be with Telerik…so take it FWIW.

First I’m going to make up some ficticious relational data. ¬†It’s totally meaningless but will be useful to test things with. ¬†So I’m going to be tracking scores of players who participate in multiple sports. ¬†Here are the classes I’ve defined to store the data.

Player class:

public class Player
{
    public string UniqueName { get; set; }

    public string SportName { get; set; }

    public string Score { get; set; }

    public DateTime AchievedDate { get; set; }
}

SportContest class and the classes inheriting from it:

public class SportContest
{
    public List<Player> Contestants { get; set; }

    public IEnumerable<Player> GetResults()
    {
        if (Contestants == null)
        {
            return null;
        }
        else
        {
            return Contestants.Where(c => c.SportName == this.GetType().Name);
        }
    }
}

public class Hockey : SportContest
{
    public void AddScore(string playerUniqueName)
    {
        if(Contestants == null)
        {
            Contestants = new List<Player>();
        }

        Player player = Contestants.FirstOrDefault(c =>
            c.UniqueName == playerUniqueName &&
            c.SportName == this.GetType().Name);

        if (player == null)
        {
            player = new Player();
            player.UniqueName = playerUniqueName;
            player.SportName = this.GetType().Name;
            player.Score = "1 goal";
            player.AchievedDate = DateTime.Now;

            Contestants.Add(player);
        }
        else
        {
            int scoreValue = Convert.ToInt32(player.Score.Substring(0, player.Score.IndexOf(" ")));
            player.Score = $"{++scoreValue} goals";
        }
    }
}

public class Baseball : SportContest
{
    public void AddScore(string playerUniqueName)
    {
        if (Contestants == null)
        {
            Contestants = new List<Player>();
        }

        Player player = Contestants.FirstOrDefault(c =>
            c.UniqueName == playerUniqueName &&
            c.SportName == this.GetType().Name);

        if (player == null)
        {
            player = new Player();
            player.UniqueName = playerUniqueName;
            player.SportName = this.GetType().Name;
            player.Score = "1 run";
            player.AchievedDate = DateTime.Now;

            Contestants.Add(player);
        }
        else
        {
            int scoreValue = Convert.ToInt32(player.Score.Substring(0, player.Score.IndexOf(" ")));
            player.Score = $"{++scoreValue} runs";
        }
    }
}

public class Football : SportContest
{
    public void AddScore(string playerUniqueName, int pointsScored)
    {
        if (Contestants == null)
        {
            Contestants = new List<Player>();
        }

        Player player = Contestants.FirstOrDefault(c =>
            c.UniqueName == playerUniqueName &&
            c.SportName == this.GetType().Name);

        if (player == null)
        {
            player = new Player();
            player.UniqueName = playerUniqueName;
            player.SportName = this.GetType().Name;
            player.Score = $"{pointsScored} {(pointsScored > 1 ? " points" : " point")}";
            player.AchievedDate = DateTime.Now;

            Contestants.Add(player);
        }
        else
        {
            int scoreValue = Convert.ToInt32(player.Score.Substring(0, player.Score.IndexOf(" ")));
            scoreValue = scoreValue + pointsScored;
            player.Score = $"{scoreValue} points";
        }
    }
}

public class Basketball : SportContest
{
    public void AddScore(string playerUniqueName, int pointsScored)
    {
        if (Contestants == null)
        {
            Contestants = new List<Player>();
        }

        Player player = Contestants.FirstOrDefault(c =>
            c.UniqueName == playerUniqueName &&
            c.SportName == this.GetType().Name);

        if (player == null)
        {
            player = new Player();
            player.UniqueName = playerUniqueName;
            player.SportName = this.GetType().Name;
            player.Score = $"{pointsScored} {(pointsScored > 1 ? " points" : " point")}";
            player.AchievedDate = DateTime.Now;

            Contestants.Add(player);
        }
        else
        {
            int scoreValue = Convert.ToInt32(player.Score.Substring(0, player.Score.IndexOf(" ")));
            scoreValue = scoreValue + pointsScored;
            player.Score = $"{scoreValue} points";
        }
    }
}

SportResults class:

public class SportResults
{
    public SportResults()
    {
        Contestants = new List<Player>();

        FillHockeyResults();
        FillBaseballResults();
        FillFootballResults();
        FillBasketballResults();
    }

    public List<Player> Contestants { get; set; }

    public Hockey Hockey { get; set; }

    public Baseball Baseball { get; set; }

    public Football Football { get; set; }

    public Basketball Basketball { get; set; }

    public void FillHockeyResults()
    {
        Random rnd = new Random(DateTime.Now.Millisecond);

        Hockey = new Hockey();
        Hockey.Contestants = Contestants;

        for (int i = 0; i < rnd.Next(); i++)
        {
            Hockey.AddScore("Albert");
        }

        for(int i = 0; i < rnd.Next(); i++)
        {
            Hockey.AddScore("Beau");
        }

        for (int i = 0; i < rnd.Next(); i++)
        {
            Hockey.AddScore("Charles");
        }

        for (int i = 0; i < rnd.Next(); i++)
        {
            Hockey.AddScore("David");
        }

        for (int i = 0; i < rnd.Next(); i++)
        {
            Hockey.AddScore("Eugene");
        }
    }

    public void FillBaseballResults()
    {
        Random rnd = new Random(DateTime.Now.Millisecond);

        Baseball = new Baseball();
        Baseball.Contestants = Contestants;

        for (int i = 0; i < rnd.Next(); i++)
        {
            Baseball.AddScore("Beau");
        }

        for (int i = 0; i < rnd.Next(); i++)
        {
            Baseball.AddScore("Charles");
        }

        for (int i = 0; i < rnd.Next(); i++)
        {
            Baseball.AddScore("David");
        }

        for (int i = 0; i < rnd.Next(); i++)
        {
            Baseball.AddScore("Eugene");
        }

        for (int i = 0; i < rnd.Next(); i++)
        {
            Baseball.AddScore("Farley");
        }
    }

    public void FillFootballResults()
    {
        Random rndTimesScored = new Random(DateTime.Now.Millisecond);
        Random rndPointsScored = new Random(DateTime.Now.Millisecond);

        Football = new Football();
        Football.Contestants = Contestants;

        for (int i = 0; i < rndTimesScored.Next(); i++)
        {
            Football.AddScore("Charles", rndPointsScored.Next(1, 7));
        }

        for (int i = 0; i < rndTimesScored.Next(); i++)
        {
            Football.AddScore("David", rndPointsScored.Next(1, 7));
        }

        for (int i = 0; i < rndTimesScored.Next(); i++)
        {
            Football.AddScore("Eugene", rndPointsScored.Next(1, 7));
        }

        for (int i = 0; i < rndTimesScored.Next(); i++)
        {
            Football.AddScore("Farley", rndPointsScored.Next(1, 7));
        }

        for (int i = 0; i < rndTimesScored.Next(); i++)
        {
            Football.AddScore("Godrick", rndPointsScored.Next(1, 7));
        }
    }

    public void FillBasketballResults()
    {
        Random rndTimesScored = new Random(DateTime.Now.Millisecond);
        Random rndPointsScored = new Random(DateTime.Now.Millisecond);

        Basketball = new Basketball();
        Basketball.Contestants = Contestants;

        for (int i = 0; i < rndTimesScored.Next(); i++)
        {
            Basketball.AddScore("David", rndPointsScored.Next(1, 3));
        }

        for (int i = 0; i < rndTimesScored.Next(); i++)
        {
            Basketball.AddScore("Eugene", rndPointsScored.Next(1, 3));
        }

        for (int i = 0; i < rndTimesScored.Next(); i++)
        {
            Basketball.AddScore("Farley", rndPointsScored.Next(1, 3));
        }

        for (int i = 0; i < rndTimesScored.Next(); i++)
        {
            Basketball.AddScore("Godrick", rndPointsScored.Next(1, 3));
        }

        for (int i = 0; i < rndTimesScored.Next(); i++)
        {
            Basketball.AddScore("Harry", rndPointsScored.Next(1, 3));
        }
    }
}

There…if you use the above code…all you have to do is instantiate a new SportResults object and you’ll have a bunch of ficticious data with some relational data between the players. ¬†Now to display that data. ¬†I whipped up a pretty basic WPF app with a RadTabControl and some RadGridViews to display the data. ¬†Here’s what my MainWindow.xaml \ cs files look like as well as the custom user control I created to display results for reach sport.

SportResultsUserControl XAML:

<UserControl    d:DesignHeight="300" 
                d:DesignWidth="300" 
                mc:Ignorable="d" 
                x:Class="ToolTipinator.PlayerStatsUserControl"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                xmlns:local="clr-namespace:ToolTipinator"
                xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <telerik:RadGridView    AutoGenerateColumns="False" 
                            ColumnWidth="*" 
                            x:Name="PlayerStatsRadGridView">
        <telerik:RadGridView.Columns>
            <telerik:GridViewDataColumn DataMemberBinding="{Binding SportName}" 
                                        Header="Sport" />
            <telerik:GridViewDataColumn DataMemberBinding="{Binding Score}" 
                                        Header="Score" />
            <telerik:GridViewDataColumn DataMemberBinding="{Binding AchievedDate}" 
                                        Header="Achieved Date" />
        </telerik:RadGridView.Columns>
    </telerik:RadGridView>
</UserControl>

SportResultsUserControl CS:

public partial class SportResultsUserControl : UserControl
{
    public SportResultsUserControl(IEnumerable&amp;lt;Player&amp;gt; contestants)
    {
        InitializeComponent();

        SportResultsRadGridView.ItemsSource = contestants;
    }
}

MainWindow XAML:

<Window Height="350" 
        Width="525" 
        Title="MainWindow" 
        x:Class="ToolTipinator.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <telerik:RadTabControl  Margin="5, 5, 5, 5" 
                                x:Name="ToolTipinatorTabControl">
            <telerik:RadTabItem BorderBrush="Black" 
                                BorderThickness="1" 
                                Header="Hockey" 
                                x:Name="HockeyRadTabItem" />
            <telerik:RadTabItem BorderBrush="Black" 
                                BorderThickness="1" 
                                Header="Baseball" 
                                x:Name="BaseballRadTabItem" />
            <telerik:RadTabItem BorderBrush="Black" 
                                BorderThickness="1" 
                                Header="Football" 
                                x:Name="FootballRadTabItem" />
            <telerik:RadTabItem BorderBrush="Black" 
                                BorderThickness="1" 
                                Header="Basketball" 
                                x:Name="BasketballRadTabItem" />
        </telerik:RadTabControl>
    </Grid>
</Window>

MainWindow CS:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        SportResults = new SportResults();

        ((RadTabItem)ToolTipinatorTabControl.Items[0]).Content = new SportResultsUserControl(SportResults.Hockey.GetResults());
        ((RadTabItem)ToolTipinatorTabControl.Items[1]).Content = new SportResultsUserControl(SportResults.Baseball.GetResults());
        ((RadTabItem)ToolTipinatorTabControl.Items[2]).Content = new SportResultsUserControl(SportResults.Football.GetResults());
        ((RadTabItem)ToolTipinatorTabControl.Items[3]).Content = new SportResultsUserControl(SportResults.Basketball.GetResults());
    }

    public SportResults SportResults { get; set; }
}

Ok…now we should all have a spiffy little WPF app that has 4 tabs one for each sport of Hockey, Baseball, Football, and Basketball.

You may notice that David and Eugene have played in each sport…and some other’s have played in 2 or 3 different sports while some have only played in a single sport. ¬†That’s where the relational data comes in and what I’ll be using in my ToolTip.

What I’m going to do next is set it up so when you hover over a player’s name, you’ll get a ToolTip popup that will display their scores in other sports. ¬†Pretty short and sweet, but it gives a good example of how to set it up. ¬†To do this I’m going to make a custom user control just for the ToolTip.

PlayerStatsUserControl XAML:

<UserControl    d:DesignHeight="300" 
                d:DesignWidth="300" 
                mc:Ignorable="d" 
                x:Class="ToolTipinator.PlayerStatsUserControl"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                xmlns:local="clr-namespace:ToolTipinator"
                xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <telerik:RadGridView    AutoGenerateColumns="False" 
                            ColumnWidth="*" 
                            x:Name="PlayerStatsRadGridView">
        <telerik:RadGridView.Columns>
            <telerik:GridViewDataColumn DataMemberBinding="{Binding SportName}" 
                                        Header="Sport" />
            <telerik:GridViewDataColumn DataMemberBinding="{Binding Score}" 
                                        Header="Score" />
            <telerik:GridViewDataColumn DataMemberBinding="{Binding AchievedDate}" 
                                        Header="Achieved Date" />
        </telerik:RadGridView.Columns>
    </telerik:RadGridView>
</UserControl>

PlayerStatsUserControl CS:

public partial class PlayerStatsUserControl : UserControl
{
    public PlayerStatsUserControl(IEnumerable&amp;lt;Player&amp;gt; contestantResults)
    {
        InitializeComponent();

        PlayerStatsRadGridView.ItemsSource = contestantResults;
    }
}

Nothing overly complex. ¬†The magic happens in a new event handler that will need to be added to the SportResultsUserControl for RowLoaded. ¬†I also added an argument to the constructor to set the sport name for the SportResults object. ¬†Here’s what my CS for my SportResultsUserControl looks like now.

SportResultsRadGridView CS:

public partial class SportResultsUserControl : UserControl
{
    public SportResultsUserControl(string sportName, IEnumerable&amp;lt;Player&amp;gt; contestants)
    {
        InitializeComponent();

        if (DesignerProperties.GetIsInDesignMode(this))
            return;

        SportName = sportName;
        SportResultsRadGridView.ItemsSource = contestants;
    }

    public string SportName { get; set; }

    private void SportResultsRadGridView_RowLoaded(object sender, RowLoadedEventArgs e)
    {
        GridViewRow currentRow = null;

        if (e.Row.GetType() == typeof(GridViewRow))
        {
            currentRow = (GridViewRow)e.Row;
        }

        if (currentRow != null)
        {
            var nameCell = currentRow.Cells.FirstOrDefault(c =&gt; c.Column.UniqueName == "UniqueName");

            if (nameCell != null)
            {
                string cellValue = ((GridViewCell)nameCell).Value.ToString();

                if (cellValue != null)
                {
                    IEnumerable&lt;Player&gt; contestantResults = MainWindow.SportResults.Contestants.Where(c =&gt; c.UniqueName == cellValue &amp;&amp; c.SportName != SportName);
                    PlayerStatsUserControl playerStatsToolTip = new PlayerStatsUserControl(contestantResults);
                    playerStatsToolTip.Width = 800;
                    nameCell.ToolTip = playerStatsToolTip;
                }
            }
        }
    }
}

In order for the above to work, I also had to turn the SportResults property that was a memeber of MainWindow into a static property so I could access it elsewhere as well as adding in the sport names to the constructor calls for the SportResultsUserControl…again, here’s what the CS for my MainWindow looks like now…

MainWindow CS:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        ToolTipService.ShowDurationProperty.OverrideMetadata(
            typeof(DependencyObject), new FrameworkPropertyMetadata(Int32.MaxValue));

        MainWindow.SportResults = new SportResults();

        ((RadTabItem)ToolTipinatorTabControl.Items[0]).Content = new SportResultsUserControl(SportResults.Hockey.GetType().Name, SportResults.Hockey.GetResults());
        ((RadTabItem)ToolTipinatorTabControl.Items[1]).Content = new SportResultsUserControl(SportResults.Baseball.GetType().Name, SportResults.Baseball.GetResults());
        ((RadTabItem)ToolTipinatorTabControl.Items[2]).Content = new SportResultsUserControl(SportResults.Football.GetType().Name, SportResults.Football.GetResults());
        ((RadTabItem)ToolTipinatorTabControl.Items[3]).Content = new SportResultsUserControl(SportResults.Basketball.GetType().Name, SportResults.Basketball.GetResults());
    }

    public static SportResults SportResults { get; set; }
}

You may notice the call to ToolTipService in the MainWindow constructor as well now. ¬†This will cause the ToolTip to stay open for about 47 days…so it’s not forever, but I’m pretty sure if a user cannot get the info they need out of a ToolTip within 47 days you have bigger problems with your app. ¬†ūüėČ

Ok…that’s it for today’s journey. ¬†Thanks for reading and as always I hope this helps someone. ¬†Enjoy! ¬†ūüôā

Setting a Custom WPF ToolTip and how to keep it shown…

From the Begining – Object Oriented Design

Hey all. ¬†Life has gotten really crazy as I’ve increased my workout schedule and been plagued with DLC for Fallout 4 so my blogging is suffering, but I’m not going to just let it end as I have more to type…and now I may even have an interested audience…someone who’s specifically asking me advice about how to get into coding.

He specifically said he just wanted to learn C#…which is something I used to say as well way back when…however what I’ve learned since then that C# more or less the adhesive that bind things together. ¬†It’s really .NET and what it can do that is the real meat of C#. ¬†And once you realize that…you find that you can use a whole bunch of different languages to do the same base .NET things and that it’s not only just C#.

What I also learned is that C# is a comfort zone…but one a person seriously wanting to learn how to code needs to break out of. ¬†Sure if you become a C# wiz, you’ll be able to slap together some cool slick object models…make some nifty libraries out of them…etc…however if you want to display anything to a user…these days you pretty much will have to know at least some minimal level of HTML / XAML. ¬†Then if you go the HTML route you’ll probably also need a little javascript / jquery. ¬†You can’t paint a modern UI picture with just C# anymore…WinForms are dying and WPF / MVC is here to stay…which is a good thing. ¬†Then if you want to store that data…sure you can write a file out to the local storage…but someone serious will want to work with a database so there will inevitably be some SQL showing up in your future…anyway, a long paragraph short, don’t be too locked down to C#…it’s a good jumping off point, but eventually you’ll need to branch out. ¬†It’s just how it is so get it in your head now.

So first let put this out there right off…I learned everything I know about C# and .NET from reading books and the internet. ¬†One of the first books I read that was extremely useful was called “Beginning C# Game Programming. ¬†Even though it’s very game centric…it does an amazing job at explaining key elements of C# / .NET and how they apply to object design in a very easy to understand way. ¬†I often look back to the chapter on polymorphism to this day.

So trying to not just plaguarize the hell out of that book…I’ll just be giving pointers as a brain dump sort of style in these “From the Begining” blog posts.

The big strength of C# is its ability to define an object. ¬†Everything in the universe boils down to being something that’s definable…C# gives you the structure to put that definition into something tangable. ¬†Very basically and simply put…these tools for structure are constructors, properties, and methods.

One of the tricks I learned early on was to take the object you’re trying to define and write a sentence out about what you’re trying to do with it.

I’m trying to count all the stars in the solar system that have planets.

Nouns are your object names and properties, verbs are your methods.

So we have “Solar System” which would be the object name. ¬†Then we have “Stars” which would be a property hanging off Solar System…which in turn has “Planets” which hangs as a property for a Star. ¬†Already we’re starting to see some structure in our definition. ¬†The tricky part is that we’re trying to count the stars that have planets…which means that the Stars object will need a “Count” method. ¬†It just so happens when you use a generic collection from .NET you get¬†a¬†Count for free (it’s a little misleading in this case because it’s a property and not a method…Count should really be a method in my way of thinking but that’s a discussion for another time). ¬†So here’s what the code would look like from the short little sentence above.

Planet Object:

public class Planet
{
    public string Name { get; set; }
}

Star Object:

public class Star
{
    public List<Planet> Planets { get; set; }
}

SolarSystem Object:

public class SolarSystem
{
    public List<Star> Stars { get; set; }
}

Really that’s all you “have” to do to get the info you need to satisfy the definition sentence. ¬†You spin through the collection of “Stars” and check the Count property of each Star object’s “Planets” property. ¬†It would look something like this…

SolarSystem milkyWay = new SolarSystem();
int starsWithPlanetsCount = 0;

foreach (Star star in milkyWay.Stars)
{
    if(star.Planets.Count > 0)
    {
        starsWithPlanetsCount++;
    }
}

…it works but lets add a couple other properties¬†to make things a little easier…so now our SolarSystem object code looks like the following…

public class SolarSystem
{
    public List<Star> Stars { get; set; }

    public List<Star> StarsWithPlanets
    {
        get
        {
            List<Star> returnList = new List<Star>();

            foreach(Star star in Stars)
            {
                if(star.Planets.Count > 0)
                {
                    returnList.Add(star);
                }
            }

            return returnList;
        }
    }

    public List<Star> StarsWithoutPlanets
    {
        get
        {
            List<Star> returnList = new List<Star>();

            foreach (Star star in Stars)
            {
                if (star.Planets.Count <= 0)
                {
                    returnList.Add(star);
                }
            }

            return returnList;
        }
    }
}

…and the calling code would look something like this…

SolarSystem milkyWay = new SolarSystem();
int starsWithPlanetsCount = milkyWay.StarsWithPlanets.Count;

So much easier and clearner. Personally I always like to keep the logic and work being done on a specific object within a method or property in that object instead of having it in calling code. ¬†It’s just a way to logically group code and make it more organized…but it’s more a personal preference thing I think.

Anyway, that’s my first lesson about C#. Use it for what it’s good for…which is defining objects. Hope this helps someone. Enjoy! ūüôā

From the Begining – Object Oriented Design

My Super Sneaky MVC Dynamic Resizing Trick

It’s been about a week since I posted last…I know, you thought you were rid of me…but HA! ¬†Nope. ¬†Today I’m going to type about MVC and Javascript stuff. ¬†I really like the layout and flexibility of MVC…I really hate the non-standard world of browsers that MVC has to support…which is probably why I’ve moved more over into the WPF world now…but anyway…

I can whip up something that looks great in Edge, but then when one of my customers goes and uses it in IE, it looks like crap. ¬†Then I solve that problem and a random person with Firefox or Chrome comes along and again it looks all out of whack…which explains my lack of hair from pulling it out in frustration! ¬†ūüėõ

Now I know there’s things you can do with css that detect what browser it’s running under and to adjust things accordingly…but honestly I find having to do that annoying. ¬†For big huge sites that are all about grabbing your attention, I can understand the need to customize and tweak the user experience per browser…but I basically make reporting apps…which shouldn’t need to be customized like crazy to make them look nice, clean, and professional. ¬†Anyway…without going on to much more of a rant about my displeasure in browser differences, here’s something I use in my MVC web apps to help dynmically resize my controls.

I work mostly with Telerik controls but my technique should work on any sort of MVC UI Element…since I’m using the class attribute to do my magic…however my examples will be shown with Telerik controls and Javascript.

First I make a little Javascript addition to my _Layout.cshtml document (in case you’re not familiar with MVC…when creating a project in Visual Studio using the MVC template it will generally always create a “Shared” view with a _Layout.cshtml document. ¬†This is a generic shared view that has a placeholder where your custom views are loaded into. ¬†If you’re an expert MVC dev and don’t use a shared layout document…you’re already well beyond this blog posts intended audience, but thanks for checking it out…hehehe). ¬†In general I only put Javascript functions that apply to every other view in my _Layout.cshtml file. ¬†In this case it’s a resizing function that gets called by a couple of events.

Javascript in _Layout.cshtml:

function ResizeElements()
{
    var bodyDiv = document.getElementById('body');
    var contentWrapper = $('#body > .content-wrapper');
    var featuredHeight = $('#body > .featured').outerHeight(true);
    var kendoGrid = $('.KendoGrid');

    // set the height of the overall body container
    bodyDiv.style.height = (window.outerHeight - 180).toString() + 'px';

    // set the width of the content wrapper.  the wrapper inherits it's height from the body container
    contentWrapper.width(window.outerWidth - 200).toString() + 'px';

    // if there is a KendoGrid class element present, set it's height so the
    // bottom is about 10 pixels from the footer
    if (kendoGrid.length > 0)
    {
        kendoGrid.height(window.outerHeight - contentWrapper - featuredHeight - 20);
        kendoGrid.data('kendoGrid').resize(); // this helps re-render the grid
    }
}

Ok, now I’ll go over what’s going on. ¬†First I create objects to work with the elements I care about instead of continuously getting them by ID (the reason I do that is because the lookup to get that object by ID is only done once if I create an object for it and then just use that object over and over…if you always just reference the object by ID…each one of those lookups “could” be a perf hit…so I just got myself into the habit of creating a reference object for these sort of things).

The “bodyDiv” object is for main <body> element of the document which every MVC document will have since they are all HTML docs.

Then I grab the element from the body which has a class of “content-wrapper” into the “contentWrapper” object which is more or less the section I use for navigation bar.

After that¬†I grab the height of the element with a class of “featured” into the “featuredHeight” object. ¬†I’m only grabbing the height because that’s really the only thing I care about in the featured section since the width is controlled by the body it’s contained within…and really I’m not getting it to set the featured section…I’m getting it so I can use the value of whatever it’s set to later.

Again, I want to be clear that the way I’m using the “content-wrapper” and “featured” classes is how a default out of box MVC templated project in Visual Studio is setup…that’s where I learned my MVC skills from so that’s the only reason I keep rolling with the way I do. ¬†If there’s better ways to go, please comment and let me know…I certainly do not know everything and would love pointers on how to do things better. ¬†ūüôā

Lastly I create an object for whatever the main display element is within my web app. ¬†In my case I use Telerik KendoGrid’s a lot. ¬†Whenever I do I add the following to the grid so it will play nicely within the view it’s in.

HtmlAttributes(new { @class = "KendoGrid" })

This adds the attribute “class=KendoGrid” onto the HTML element for the grid…and my ResizeElements method is trying to create an object out of elements with a class of “KendoGrid”…ahhhh there’s the magic.

So now that I have objects for the things I want to work with…now I start setting the the dimensions. ¬†For the body I force it to be specific size based on the “window”. ¬†In this context “window” refers to the window of whatever browser you’re using to display the web app. ¬†So I set the body’s height to a size I control that is less than the browser windows’s height…now I know my body element will never be longer¬†than what’s showing on the screen.

Next I set the width of the content wrapper which in turn also sets the width of the body. ¬†I think the way I’m doing it could be a little dangerous in that I’m counting on this controlling the width of all my other elements…it works but I can see where property inheritance could cause some troubles…but since I’m the one creating all the custom views it’s not terribly dangerous. ¬†I think if I worked in a big team I’d design something a little more robust…but for now, this works great for me.

Ok, so that’s height and width…however if I just put a grid in my custom view like this…it looks like crap which is where the block of code checking for kendoGrid.length comes into play. ¬†Technically there’s probably a better way to do what I’m doing…but again since I control the custom views, I know there’s always only going to be 1 or less grids in my views so I really just care if “length” is greater than 0…although I should probably write some code to throw an error if there’s more than 1…maybe later. ¬†ūüôā

So what I’m doing in that “if block” is setting the height of the grid to be less than the windows outer height – the content wrapper – the featured height – an extra 20 pixels just to make sure the grid has some margins and isn’t squishing anything. ¬†Now as soon as the page loads, the grid is alread the correct size…and if there’s more records than fits within the grid, a horizontal scroll bar will display in the grid instead of the web app’s main page…which is a much nicer scrolling experience IMHO.

The last part of the equation is to add a couple more Javascript functions to _Layout.cshtml. ¬†One will fire as soon as the document is finished loading…the other will fire every time the document is resized. ¬†Both just execute the method we created perviously called “ResizeElements()”.

$(document).ready(function ()
{
    ResizeElements();
});

$(window).resize(function()
{
    ResizeElements();
});

So that’s pretty much all there’s to my super sneaky resizing trick. ¬†This is what works for me in my workplace and makes my boss happy…but I’m sure by now you can see what I was doing and apply it to your own beautification techniques. ¬†Hope it helped…Enjoy! ¬†ūüôā

My Super Sneaky MVC Dynamic Resizing Trick