WPFSpark v1.3 Released

Yesterday (Jul 10th, 2016), I released WPFSpark v1.3 on GitHub & NuGet. In this version I have updated the Layout logic of FluidWrapPanel with a more robust code. Now it rearranges the variable sized children in a more efficient manner.

Also, I upgraded the target DotNet Framework of the WPFSpark project from 4.6.1 to 4.6.2.

If you are installing this version in your project, please ensure that your project is also targeting the version 4.6.2 of the DotNet Framework.

Retiring WPFSpark.UWP project

I will be retiring the WPFSpark.UWP project soon. Having controls used for UWP project and keeping the project name “WPFSpark” did not make sense (as WPF is limited to Windows 10 desktop projects). As of now WPFSpark.UWP project contains only the FluidWrapPanel control. I will be moving the control (and its source code) to the CompositionProToolkit project.

CompositionProToolkit

CompositionProToolkit is a collection of helper classes for Windows.UI.Composition. It also contains the FluidProgressRing control which is a concept design for a modern version of the ProgressRing control in UWP.

FluidProgressRing.gif

I have currently ported the FluidWrapPanel code in WPFSpark v1.3 to UWP and now I am trying to use Windows.UI.Composition APIs to replace the XAML animations used in FluidWrapPanel. This would result in smoother animations in FluidWrapPanel control. This work is currently in progress and I hope to release it soon.

Advertisements

9 thoughts on “WPFSpark v1.3 Released

  1. Hello,
    I would like to use the ClipBorder control from WPFSpark, but I don’t want to install Net 4.6.2, since it is only in preview state. I have Net 4.6.1 installed, so where can I download WPFSpark v1.2?

    1. Hi,
      WPFSpark v1.2.1.1 is now available for download in NuGet. This will be discontinued when 4.6.2 RTM releases. Alternatively, you can download the WPFSpark source code from GitHub and retarget the project to 4.6.1 and build it locally.

  2. Hi Ratish,
    I am trying to utilize your FluidWrapPanel control in a project. So far everything works great. I was wondering how difficult it would be to implement an additional feature. What I would like to implement is an alteration to the flow direction of each newly added child. I would like the children to be added in alternating directions.

    I should note that I’m working in WPF, as the intended program will not be running on Windows 10.
    Example:
    With orientation set to vertical…
    Fill the first column from top to bottom, then fill the second column from bottom to top.
    ——————–
    1 6 7
    2 5 8
    3 4 9
    ——————–
    Currently, with the same orientation set the FluidWrapPanel will populate from the top on every column.
    I would ultimately like the flexibility of having the Orientation set to either Horizontal or Vertical. But if you could provide a code sample, or a starting point for just one of those scenarios that would be great.

    I would also ask if you could point me in the right direction as far as implementing this, as your FluidWrapPanel is a bit over my head. I’ve read a few tutorials on writing custom panels, but your custom panel takes everything I’ve seen to a whole new level.

    Thank you for your time, and thank you for sharing.

    1. HI Patrick,
      I’m glad that you find the FluidWrapPanel very useful.

      The scenario you explained is certainly doable. The difficulty of implementing it depends on the following criteria – are the children of the FluidWrapPanel have the same size as the Item size (i.e. ItemWidth x ItemHeight) or are they having different sizes.

      The core logic of finding where the next child is to be placed is handled by the FluidBitMatrix class. This class is the bit representation of the FluidWrapPanel where each bit represents the unit size (i.e. ItemWidth x ItemHeight).

      In this class, the TryFindRegion API finds the next unset bit (or bits if the child has a size which is a multiple of ItemWidth or ItemHeight) in the FluidBitMatrix. The bit location represents the location of the child in the FluidWrapPanel.

      So if all your children are of unit size, the modification is simple. In the TryFindRegion, I am first checking if both the width and height are equal to 1. In that code scope you have to alter the way the two nested loops are iterating to suit your alternating directions.

      On the other hand, if your children are of varying sizes, then the situation is a bit tricky. The remainder of the code in the TryFindRegion API deals with this scenario and needs to be modified with care.

      Hope it helps!

      1. Thank you Ratish for your quick reply. The sizes of each child added to the FluidWrapPanel is going to vary within a set of specific rules:
        1. All children will be the same height.
        2. The standard (and most often occurring child) will be a specific width.
        3. The only other size variation that will occur is a double wide child object. This object is twice as wide as the standard.

        By reading your comment about the unit size I assume that I will have different unit sizes when comparing the standard, and double wide.
        But I would need to accommodate both situations since the children in the FluidWrapPanel is going to vary based on what the User adds. (Either the children will all be the same size, or it will be mixed between Standard and Double Wide).

        Looking through TryFindRegion, I believe I can see what you are referring to as far as changing how to two nested loops iterate.
        It seems to me that I have to modify the startIndex because this is “The row to start the search from”.
        If I define the startIndex as the last item in the row (is that possible?), then I could iterate backwards in the outermost for loop:
        // Optimization: If both width and height are 1 then use a faster
        // loop to find the next empty cell
        if ((width == 1) && (height == 1))
        {
        for (var row = startIndex; row < _rowsInternal; row–)
        {
        for (var col = 0; col < _columnsInternal; col++)
        {
        // Is the cell unset?
        if (this[row, col])
        continue;

        // Swap the row and col values if the BitOrientation is Vertical
        cell = (BitOrientation == Orientation.Horizontal) ? new MatrixCell(row, col) : new MatrixCell(col, row);
        return true;
        }
        }
        However, this parameter is defined in the FluidWrapPanel class itself, which you did not specifically mention. So I'll let you comment further on that.

        I can't test this further, because I don't really know how to implement my theory if its even correct.

  3. You don’t have to modify startIndex. You have to modify how the inner loop iterates.

    No matter what the orientation is, FluidBitMatrix calculates the location in the Horizontal orientation and while returning the location it interchanges the row and column if the Orientation is vertical.

    So the TryFindRegion assumes that all the bits in rows 0 to startIndex – 1 have their bits set and have to start looking for the best location from startIndexth row onwards.

    So the modification required for handling children, having unit size each, is

    if ((width == 1) && (height == 1))
    {
    for (var row = startIndex; row < _rowsInternal; row++)
    {
    var isReverse = (row % 2) == 1;
    var start = isReverse ? _columnsInternal - 1 : 0;
    var end = isReverse ? -1 : _columnsInternal;
    var incr = isReverse ? -1 : 1;
    for (var col = start; isReverse ? (col > end) : (col < end); col += incr)
    {
    // Is the cell unset?
    if (this[row, col])
    continue;

    // Swap the row and col values if the BitOrientation is Vertical
    cell = (BitOrientation == Orientation.Horizontal) ? new MatrixCell(row, col) : new MatrixCell(col, row);
    return true;
    }
    }

    // If the code has reached here it means that it did not find any unset
    // bit in the entire matrix. Return false from here.
    return false;
    }

    As for children of varying sizes, if the current row is odd, you have to modify the rest of the code in the method and also the AnyBitsSetInRegion API so that it can search for a place to fit 'width' bits from the last column in the row and moving back towards the first column.

    1. Ratish,
      This is a great start. Thank you very much. I’ve got your code snippet inserted and working in your WPFSpark sample project. I am having issues with it actually working in my project. But I’ll figure that part out in time. After thinking about it for a while, it may not even be all that necessary to after the second part of the TryFindRegion for my situation. The likelihood of there being more than one double wide object in the panel is pretty low. So its not critical if that one child is out of place. Of course I will try and get it working, but you’ve solved the bulk of my issues with just that first part.

      Again, thank you
      And I’ll let you know of my progress.

      -Pat

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s