示例#1
0
        public override void ResolveSublayoutReferences()
        {
            //	Call the base class implementation to resolve any sublayouts
            //	that were declared statically in the design file
            base.ResolveSublayoutReferences();

            //	Create dynamic sublayouts based on our source reference. These
            //	new sublayouts will be resolved as soon as we create them
            //	because we'll be passing resolved references to them.
            List <Reference> items = new List <Reference>();

            switch (_sourcePath.TargetType)
            {
            case ContentSourceType.Checkbox:
            case ContentSourceType.RadioButton:
            case ContentSourceType.TextEntry:
            case ContentSourceType.Calculation:
            case ContentSourceType.Section:
                items.Add(_sourceObject);
                break;

            case ContentSourceType.MultiSelect:
            case ContentSourceType.SingleSelect:
            case ContentSourceType.CalculationList:
                //	Include all the items in the source list
                List <Reference> children = _generator.Resolver.GetChildren(_sourceObject);
                items.AddRange(children);
                break;
            }
            //	We want the dynamic sublayouts based on our source reference to appear
            //	first in the list, before static layouts defined in the design file.
            //	The static layouts have already been added by the call to the base
            //	class implementation of this method (which must be called before we
            //	do our own stuff here, because it clears _subLayouts) and so we want
            //	to start inserting the dynamic layouts at index zero. To preserve the
            //	internal order of those dynamic layouts, we increment the insert
            //	index for each one.
            int insertIndex = 0;

            foreach (Reference item in items)
            {
                bool satisfies = _conditions.SatisfiesContentConditions(item);
                if (!satisfies)
                {
                    continue;
                }

                TextLayout layout = new TextLayout(item, _style.ItemStyle, _generator, _trackingInfo.LineNumber, _trackingInfo.LinePosition);
                InsertSubLayout(insertIndex++, layout);
            }

            //TODO: For calculations, which have complex structure, a complex rendition
            //comprised of any of the calculation's parts - caption, value and unit of
            //measure - all in a single list item. For example, "price : $10.00" or
            //"size = 30sq.m.". I think this is easy enough to do in a text layout,
            //and we could embed a text layout in the list, but then how would we repeat
            //the text layout for all calculations that the source reference resolves to?
            //Do we need to add a "pattern" attribute to ListLayout? Something like
            //	<ListLayout source="CalculationList:1234[...]" pattern="!Caption = !Value!UnitOfMeasure">
            //See Jira ticket DEMON-268.

            //	Merge sublists into this list
            MergeSubLists();

            //	Pass on our static conditions to our items so that they can
            //	apply them when they load their content
            foreach (Layout layout in _subLayouts)
            {
                layout.AddConditions(_conditions);
            }

            //	Wrap our sublayouts in list items
            List <Layout> wrapped = WrapSublayouts(_subLayouts);

            //	Set ourself as the container on each of the wrappers. Creating the
            //	wrappers has automatically made each wrapper the container of its
            //	content layout, replacing us. Making ourself the container of the
            //	wrappers keeps the container hierarchy intact. The hierarchy must
            //	be maintained so that reference resolution can have correct context.
            _subLayouts.Clear();
            foreach (Layout sublayout in wrapped)
            {
                AddSubLayout(sublayout);
            }

            //	Prepare our empty text in case we need to use it later. Even if we have
            //	some items now, after applying conditions we may be left with none,
            //	in which case we'll need our empty text.
            if (!string.IsNullOrWhiteSpace(_emptyText))
            {
                ListStyle style = _emptyStyle ?? _style;
                _whenEmpty = new TextLayout(_emptyText, style.ItemStyle, _generator, _trackingInfo.LineNumber, _trackingInfo.LinePosition);
                List <Layout> unwrapped = new List <Layout>();
                unwrapped.Add(_whenEmpty);
                wrapped    = WrapSublayouts(unwrapped);
                _whenEmpty = wrapped[0];
            }

            //	Use our empty layout right away if we're empty
            if ((_subLayouts.Count == 0) && (_whenEmpty != null))
            {
                AddSubLayout(_whenEmpty);
            }
        }