EntityDataSourceDataSelection.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataWebControlsDesign / System / Data / WebControls / Design / EntityDataSourceDataSelection.cs / 1 / EntityDataSourceDataSelection.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
// 
// Manages the properties that can be set on the second page of the wizard
//----------------------------------------------------------------------------- 

using System.Collections.Generic;
using System.Data.Entity;
using System.Diagnostics; 
using System.Globalization;
using System.Text; 
using System.Web.Resources.Design; 
using System.Web.UI.Design.Util;
 
namespace System.Web.UI.Design.WebControls
{
    internal class EntityDataSourceDataSelection
    { 
        #region Private static fields
        // iterator prefix used in building and parsing Select property value 
        private static readonly string s_itKeyword = "it."; 
        // Placeholder item to indicate (None) on the EntityTypeFilter ComboBox
        private static readonly EntityDataSourceEntityTypeFilterItem s_entityTypeFilterNoneItem = 
                new EntityDataSourceEntityTypeFilterItem(Strings.Wizard_DataSelectionPanel_NoEntityTypeFilter);
        #endregion

        #region Private readonly fields 
        private readonly EntityDataSourceDataSelectionPanel _panel;
        private readonly EntityDataSourceDesignerHelper _helper; 
        #endregion 

        #region Private fields for temporary storage of property values 
        private readonly EntityDataSourceState _entityDataSourceState;
        private List _entitySetNames;
        private EntityDataSourceEntitySetNameItem _selectedEntitySetName;
        private List _entityTypeFilters; 
        private EntityDataSourceEntityTypeFilterItem _selectedEntityTypeFilter;
 
        #region Select views 
        // The Data Selection wizard panel can display two kinds of views of the Select property:
        //     (1) Simple Select View: CheckedListBox with a list of available entity type properties 
        //     (2) Advanced Select View: TextBox that allows any statement to be entered (no validation)
        //
        // When either view is visible to the user, the fields shown below for that view should be non-null, and the fields
        // for the other view should be null. 

        // Simple Select View 
        // _selectedEntityTypeProperties contains a set of indexes of properties in _entityTypeProperties 
        private List _entityTypeProperties;
        private List _selectedEntityTypeProperties; 

        // Advanced Select View
        private string _select;
        #endregion 

        private bool _enableInsert; 
        private bool _enableUpdate; 
        private bool _enableDelete;
        private readonly EntityDataSourceWizardForm _wizardForm; 
        #endregion

        #region Constructors
        internal EntityDataSourceDataSelection(EntityDataSourceDataSelectionPanel panel, EntityDataSourceWizardForm wizard, EntityDataSourceDesignerHelper designerHelper, EntityDataSourceState entityDataSourceState) 
        {
            _panel = panel; 
            _panel.Register(this); 
            _helper = designerHelper;
 
            _entityDataSourceState = entityDataSourceState;
            _wizardForm = wizard;
        }
        #endregion 

        #region Events 
        // Event handler to process notifications when a DefaultContainerName is selected on the ObjectContext configuration panel 
        internal void ContainerNameChangedHandler(object sender, EntityDataSourceContainerNameItem newContainerName)
        { 
            // Load the entity sets for this container, don't select anything initially in the list
            LoadEntitySetNames(newContainerName, null);

            // Reset the other controls that depend on the value of EntitySet 
            LoadEntityTypeFilters(null, null);
            LoadSelect(String.Empty); 
        } 
        #endregion
 
        #region Methods to manage temporary state and wizard contents
        // Used when the wizard is launched, to load existing property values from data source control
        internal void LoadState()
        { 
            LoadEntitySetNames(_helper.GetEntityContainerItem(_entityDataSourceState.DefaultContainerName), _entityDataSourceState.EntitySetName);
            LoadEntityTypeFilters(_selectedEntitySetName, _entityDataSourceState.EntityTypeFilter); 
            LoadSelect(_entityDataSourceState.Select); 
            LoadInsertUpdateDelete();
        } 

        // Save current wizard settings back to the EntityDataSourceState
        internal void SaveState()
        { 
            SaveEntitySetName();
            SaveEntityTypeFilter(); 
            SaveSelect(); 
            SaveInsertUpdateDelete();
        } 

        #region EntitySetName
        // Find the specified entitySetName in the list or add it if it's not there
        private EntityDataSourceEntitySetNameItem FindEntitySetName(string entitySetName) 
        {
            if (!String.IsNullOrEmpty(entitySetName)) 
            { 
                EntityDataSourceEntitySetNameItem entitySetToSelect = null;
                foreach (EntityDataSourceEntitySetNameItem entitySetNameItem in _entitySetNames) 
                {
                    // Ignore case here when searching the list for a matching item, but set the temporary state property to the
                    // correctly-cased version from metadata so that if the user clicks Finish, the correct one will be saved. This
                    // allows some flexibility the designer without preserving an incorrectly-cased value that could cause errors at runtime. 
                    if (String.Equals(entitySetNameItem.EntitySetName, entitySetName, StringComparison.OrdinalIgnoreCase))
                    { 
                        entitySetToSelect = entitySetNameItem; 
                    }
                } 

                // didn't find a matching entityset, so just create a placeholder for one using the specified name and add it to the list
                if (entitySetToSelect == null)
                { 
                    entitySetToSelect = new EntityDataSourceEntitySetNameItem(entitySetName);
                    _entitySetNames.Add(entitySetToSelect); 
                } 

                Debug.Assert(entitySetToSelect != null, "expected a non-null EntityDataSourceEntitySetNameItem"); 
                return entitySetToSelect;
            }

            return null; 
        }
 
        // Populates the EntitySetName combobox with all of the discoverable EntitySets for the specified container. 
        // If the specified entitySetName is not empty, it is added to the list and selected as the initial value
        // containerNameItem may not be backed by a real EntityContainer, in which case there is no way to look up the EntitySet in metadata 
        // devnote: This method should not automatically reset EntityTypeFilter and Select because it can be used to load the initial state
        //          for the form, in which case we need to preserve any values that are already set on the data source control.
        private void LoadEntitySetNames(EntityDataSourceContainerNameItem containerNameItem, string entitySetName)
        { 
            // If this is a container that we found in the project's metadata, get a list of EntitySets for that container
            if (containerNameItem != null && containerNameItem.EntityContainer != null) 
            { 
                _entitySetNames = _helper.GetEntitySets(containerNameItem.EntityContainer, false /*sortResults*/);
 
                // Try to find the specified entityset in list and add it if it isn't there
                _selectedEntitySetName = FindEntitySetName(entitySetName);
            }
            else 
            {
                // if this is an unknown container, there is no way to find a list of entitysets from metadata 
                // so just create a new list and placeholder for the specified entityset 
                _entitySetNames = new List();
                if (!String.IsNullOrEmpty(entitySetName)) 
                {
                    _selectedEntitySetName = new EntityDataSourceEntitySetNameItem(entitySetName);
                    _entitySetNames.Add(_selectedEntitySetName);
                } 
                else
                { 
                    _selectedEntitySetName = null; 
                }
            } 

            // Sort the list now, after we may have added one above
            _entitySetNames.Sort();
 
            // Update the controls
            _panel.SetEntitySetNames(_entitySetNames); 
            _panel.SetSelectedEntitySetName(_selectedEntitySetName); 
        }
 
        // Set EntitySetName in temporary storage
        internal void SelectEntitySetName(EntityDataSourceEntitySetNameItem selectedEntitySet)
        {
            _selectedEntitySetName = selectedEntitySet; 
            // Load the types for the selected EntitySet, don't select one initially
            LoadEntityTypeFilters(selectedEntitySet, null); 
            // Reinitialize the Select control with a list of properties, don't preserve any existing Select value 
            LoadSelect(String.Empty);
        } 

        private void SaveEntitySetName()
        {
            if (_selectedEntitySetName != null) 
            {
                _entityDataSourceState.EntitySetName = _selectedEntitySetName.EntitySetName; 
            } 
            else
            { 
                _entityDataSourceState.EntitySetName = String.Empty;
            }
        }
        #endregion 

        #region EntityTypeFilter 
        // Populate a list with the base type for the EntitySet plus all derived types, and a special entry to indicate no filter 
        // devnote: This method should not automatically reset Select because it can be used to load the initial state
        //          for the form, in which case we need to preserve any values that are already set on the data source control. 
        private void LoadEntityTypeFilters(EntityDataSourceEntitySetNameItem entitySetItem, string entityTypeFilter)
        {
            // If this is an EntitySet that we found in the project's metadata, get the type information
            if (entitySetItem != null && entitySetItem.EntitySet != null) 
            {
                _entityTypeFilters = _helper.GetEntityTypeFilters(entitySetItem.EntitySet.ElementType, false /*sortResults*/); 
                // add (None) to the beginning of the list 
                _entityTypeFilters.Insert(0, s_entityTypeFilterNoneItem);
 
                // Try to find the specified type in list and add it if it isn't there
                _selectedEntityTypeFilter = FindEntityTypeFilter(entityTypeFilter);
            }
            else 
            {
                // if this is an unknown EntitySet, there is no way to find a list of types from metadata 
                // so just create a new list and placeholder for the specified type 
                _entityTypeFilters = new List();
                _entityTypeFilters.Add(s_entityTypeFilterNoneItem); 

                if (!String.IsNullOrEmpty(entityTypeFilter))
                {
                    _selectedEntityTypeFilter = new EntityDataSourceEntityTypeFilterItem(entityTypeFilter); 
                    _entityTypeFilters.Add(_selectedEntityTypeFilter);
                } 
                else 
                {
                    _selectedEntityTypeFilter = s_entityTypeFilterNoneItem; 
                }
            }

            // Sort now after we might have added items above 
            _entityTypeFilters.Sort();
 
            // Update the controls 
            _panel.SetEntityTypeFilters(_entityTypeFilters);
            _panel.SetSelectedEntityTypeFilter(_selectedEntityTypeFilter); 
        }

        // Find the specified entityTypeFilter in the list and add it if it's not there
        private EntityDataSourceEntityTypeFilterItem FindEntityTypeFilter(string entityTypeFilter) 
        {
            if (!String.IsNullOrEmpty(entityTypeFilter)) 
            { 
                EntityDataSourceEntityTypeFilterItem typeToSelect = null;
                foreach (EntityDataSourceEntityTypeFilterItem entityTypeFilterItem in _entityTypeFilters) 
                {
                    // Ignore case here when searching the list for a matching item, but set the temporary state property to the
                    // correctly-cased version from metadata so that if the user clicks Finish, the correct one will be saved. This
                    // allows some flexibility the designer without preserving an incorrectly-cased value that could cause errors at runtime. 
                    if (String.Equals(entityTypeFilterItem.EntityTypeName, entityTypeFilter, StringComparison.OrdinalIgnoreCase))
                    { 
                        typeToSelect = entityTypeFilterItem; 
                    }
                } 

                // didn't find a matching type, so just create a placeholder item and add it to the list
                if (typeToSelect == null)
                { 
                    typeToSelect = new EntityDataSourceEntityTypeFilterItem(entityTypeFilter);
                    _entityTypeFilters.Add(typeToSelect); 
 
                }
 
                Debug.Assert(typeToSelect != null, "expected a non-null string for EntityTypeFilter");
                return typeToSelect;
            }
 
            return s_entityTypeFilterNoneItem;
        } 
 
        // Set EntityTypeFilter in temporary storage and load the Select property
        internal void SelectEntityTypeFilter(EntityDataSourceEntityTypeFilterItem selectedEntityTypeFilter) 
        {
            _selectedEntityTypeFilter = selectedEntityTypeFilter;
            // Reinitialize the Select control with a list of properties, don't preserve any existing Select value
            LoadSelect(String.Empty); 
        }
 
        private void SaveEntityTypeFilter() 
        {
            // If (None) is selected, it is the same as an empty string on the data source control 
            if (Object.ReferenceEquals(_selectedEntityTypeFilter, s_entityTypeFilterNoneItem))
            {
                _entityDataSourceState.EntityTypeFilter = String.Empty;
            } 
            else
            { 
                _entityDataSourceState.EntityTypeFilter = _selectedEntityTypeFilter.EntityTypeName; 
            }
        } 

        #endregion

        #region Select 
        // Load and parse the Select property
        private void LoadSelect(string select) 
        { 
            Debug.Assert(_selectedEntityTypeFilter != null, "_selectedEntityTypeFilter should never be null");
 
            System.Data.Metadata.Edm.EntityType entityType = null;

            // determine which EntityType to load properties for, based on the value selected for EntityTypeFilter
            if (Object.ReferenceEquals(_selectedEntityTypeFilter, s_entityTypeFilterNoneItem)) 
            {
                // If (None) is selected, use the base type for the EntitySet if available 
                if (_selectedEntitySetName != null && _selectedEntitySetName.EntitySet != null) 
                {
                    entityType = _selectedEntitySetName.EntitySet.ElementType; 
                }
                // else the EntitySet base type is not known
            }
            else 
            {
                entityType = _selectedEntityTypeFilter.EntityType; // could still be null if the type if not known in metadata 
            } 

            if (entityType != null) 
            {
                // this is a real type from metadata, load its properties
                _entityTypeProperties = _helper.GetEntityTypeProperties(entityType);
                // add the 'Select All (Entity Value)' placeholder at the beginning of the list 
                _entityTypeProperties.Insert(0, Strings.Wizard_DataSelectionPanel_SelectAllProperties);
 
                // parse the current value for the Select property to see if it can be displayed in the simple CheckedListBox view 
                if (TryParseSelect(select))
                { 
                    _select = null;

                    // Update the controls
                    _panel.SetEntityTypeProperties(_entityTypeProperties, _selectedEntityTypeProperties); 
                    UpdateInsertUpdateDeleteState();
                    return; 
                } 
                // else we failed to parse the select into entity type properties on the specified type, so just use the advanced select view
            } // else can't get a list of properties unless we have a known EntityType 


            // if we don't have a valid entity type or couldn't parse the incoming Select value, just display the advanced TextBox view
            _entityTypeProperties = null; 
            _selectedEntityTypeProperties = null;
            _select = select; 
 
            // Update the controls
            _panel.SetSelect(_select); 
            UpdateInsertUpdateDeleteState();
        }

        // Build a value for the Select property from the selected values in the CheckedListBox 
        // Value will be in the from "it.Property1, it.Property2, it.Property3"
        private string BuildSelect() 
        { 
            Debug.Assert(_selectedEntityTypeProperties != null && _selectedEntityTypeProperties.Count > 0, "expected non-null _selectedEntityTypeProperties with at least one value");
 
            // 'Select All (Entity Value)' is the same thing as an empty string for the property
            if (_selectedEntityTypeProperties[0] == 0)
            {
                Debug.Assert(_selectedEntityTypeProperties.Count == 1, "'Select All (Entity Value)' should be the only property selected"); 
                return String.Empty;
            } 
 
            StringBuilder selectProperties = new StringBuilder();
            bool addComma = false; 
            foreach (int propertyIndex in _selectedEntityTypeProperties)
            {
                if (addComma)
                { 
                    selectProperties.Append(", ");
                } 
                else 
                {
                    addComma = true; 
                }

                selectProperties.AppendFormat(CultureInfo.InvariantCulture, "{0}{1}", s_itKeyword, EscapePropertyName(_entityTypeProperties[propertyIndex]));
 
            }
            return selectProperties.ToString(); 
        } 

        private static string EscapePropertyName(string propertyName) 
        {
            return "[" + propertyName.Replace("]", "]]") + "]";
        }
 
        static string UnescapePropertyName(string name)
        { 
            if (name[0] == '[' && name[name.Length - 1] == ']') 
            {
                return name.Substring(1, name.Length - 2).Replace("]]", "]"); 
            }
            else
            {
                // else the property is not escaped at all or is not properly escaped. We can't parse it so just return. 
                return name;
            } 
        } 

        // Parses the current Select property on the data source to see if it matches a specific format that we can use to display the properties 
        // in the CheckedListBox in the simple select wizard view
        private bool TryParseSelect(string currentSelect)
        {
            bool parseSuccess = false; // gets set to true after the statement has been successfully parsed 
            if (!String.IsNullOrEmpty(currentSelect))
            { 
                // first try to split the string up into pieces divided by commas 
                // expects a format like the following: (extra spaces around the commas should work as well)
                //     "it.KnownPropertyName1, it.KnownPropertyName2, it.KnownPropertyName3" 
                string[] tokenizedSelect = currentSelect.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                bool foundUnknownProperty = false;
                List selectedProperties = new List(); 
                foreach (string token in tokenizedSelect)
                { 
                    string propertyName = token.Trim(); 

                    // Does the current property token start with "it."? 
                    if (ReadItKeyword(propertyName))
                    {
                        // Does the rest of the property token match a known property name for the selected EntityTypeFilter?
                        int propertyIndex = ReadPropertyName(propertyName.Substring(s_itKeyword.Length)); 
                        if (propertyIndex == -1)
                        { 
                            // the property was not known, so we can just stop looking 
                            foundUnknownProperty = true;
                            break; 
                        }
                        else
                        {
                            // this is a known property, so add its index to the list 
                            selectedProperties.Add(propertyIndex);
                        } 
                    } 
                    else
                    { 
                        // the property was not known, so we can just stop looking
                        foundUnknownProperty = true;
                        break;
                    } 
                }
                if (!foundUnknownProperty) 
                { 
                    // if we never found anything unknown, the current list of properties is what we'll use to fill in the CheckedListBox
                    _selectedEntityTypeProperties = selectedProperties; 
                    parseSuccess = true;
                }
                else
                { 
                    _selectedEntityTypeProperties = null;
                } 
            } 
            else
            { 
                // if Select is empty, we just want to add 'Select All (Entity Value)' to the list
                _selectedEntityTypeProperties = new List();
                _selectedEntityTypeProperties.Add(0);
                parseSuccess = true; 
            }
 
            return parseSuccess; 
        }
 
        // Determines if the specified propertyName starts with "it." (case-insensitive)
        private bool ReadItKeyword(string propertyName)
        {
            // will accept any casing of "it." here, although when the value is saved back to the property, it will be correctly lower-cased 
            return propertyName.StartsWith(s_itKeyword, StringComparison.OrdinalIgnoreCase);
        } 
 
        // Determines if the specified propertyName matches one of the known properties for the selected type
        private int ReadPropertyName(string propertyName) 
        {
            for (int propIndex = 0; propIndex < _entityTypeProperties.Count; propIndex++)
            {
                // Ignore case here when searching the list for a matching item, but set the temporary state property to the 
                // correctly-cased version from metadata so that if the user clicks Finish, the correct one will be saved. This
                // allows some flexibility the designer without preserving an incorrectly-cased value that could cause errors at runtime. 
 
                // Does the specified property name exactly match any of the properties for the selected EntityTypeFilter?
                if (String.Equals(UnescapePropertyName(propertyName), _entityTypeProperties[propIndex], StringComparison.OrdinalIgnoreCase)) 
                {
                    return propIndex;
                }
            } 

            return -1; 
        } 

        // Add the specified property to the list of selected entity properties used to build up the Select property 
        internal void SelectEntityProperty(int propertyIndex)
        {
            _selectedEntityTypeProperties.Add(propertyIndex);
        } 

        internal void ClearAllSelectedProperties() 
        { 
            _selectedEntityTypeProperties.Clear();
        } 

        // Remove specified entity property index from the selected list
        internal void DeselectEntityProperty(int propertyIndex)
        { 
            _selectedEntityTypeProperties.Remove(propertyIndex);
        } 
 
        // Set Select property to the specified string (used with advanced select view)
        internal void SelectAdvancedSelect(string select) 
        {
            _select = select;
        }
 
        private void SaveSelect()
        { 
            if (_select != null) 
            {
                _entityDataSourceState.Select = _select; 
            }
            else
            {
                Debug.Assert(_selectedEntityTypeProperties != null, "expected _entityTypeProperties to be non-null if _select is null"); 
                _entityDataSourceState.Select = BuildSelect();
            } 
        } 
        #endregion
 
        #region EnableInsertUpdateDelete
        // Load the initial values for EnableInsert/EnableUpdate/EnableDelete CheckBoxes
        private void LoadInsertUpdateDelete()
        { 
            SelectEnableInsert(_entityDataSourceState.EnableInsert);
            SelectEnableUpdate(_entityDataSourceState.EnableUpdate); 
            SelectEnableDelete(_entityDataSourceState.EnableDelete); 

            UpdateInsertUpdateDeleteState(); 
        }

        // Set EnableDelete in temporary storage
        internal void SelectEnableDelete(bool enableDelete) 
        {
            _enableDelete = enableDelete; 
        } 

        // Set EnableInsert in temporary storage 
        internal void SelectEnableInsert(bool enableInsert)
        {
            _enableInsert = enableInsert;
        } 

        // Set EnableUpdate in temporary storage 
        internal void SelectEnableUpdate(bool enableUpdate) 
        {
            _enableUpdate = enableUpdate; 
        }

        private void SaveInsertUpdateDelete()
        { 
            _entityDataSourceState.EnableInsert = _enableInsert;
            _entityDataSourceState.EnableUpdate = _enableUpdate; 
            _entityDataSourceState.EnableDelete = _enableDelete; 
        }
 
        /// 
        /// Update the panel control state based on the valued of enableInsert,
        /// enableUpdate, enableDelete, and the selectedEntityTypeProperties
        ///  
        internal void UpdateInsertUpdateDeleteState()
        { 
            // Set the checkbox state for the panel controls 
            _panel.SetEnableInsertUpdateDelete(_enableInsert, _enableUpdate, _enableDelete);
 
            // The InsertUpdateDelete panel should be enabled if:
            // 1. Insert, Update, or Delete is selected -OR-
            // 2. The EntitySelection has SelectAll checked
            bool enablePanel = (_enableInsert || _enableUpdate || _enableDelete || 
                        (_selectedEntityTypeProperties != null &&
                         _selectedEntityTypeProperties.Count == 1 && 
                         _selectedEntityTypeProperties[0] == 0)); 

            _panel.SetEnableInsertUpdateDeletePanel(enablePanel); 
        }
        #endregion
        #endregion
 
        #region Wizard button state management
        internal void UpdateWizardState() 
        { 
            // EntitySetName must be selected and a Select must be configured or must be the empty string
            _wizardForm.SetCanFinish(_selectedEntitySetName != null && (_select != null || _selectedEntityTypeProperties.Count > 0)); 
        }
        #endregion
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
// 
// Manages the properties that can be set on the second page of the wizard
//----------------------------------------------------------------------------- 

using System.Collections.Generic;
using System.Data.Entity;
using System.Diagnostics; 
using System.Globalization;
using System.Text; 
using System.Web.Resources.Design; 
using System.Web.UI.Design.Util;
 
namespace System.Web.UI.Design.WebControls
{
    internal class EntityDataSourceDataSelection
    { 
        #region Private static fields
        // iterator prefix used in building and parsing Select property value 
        private static readonly string s_itKeyword = "it."; 
        // Placeholder item to indicate (None) on the EntityTypeFilter ComboBox
        private static readonly EntityDataSourceEntityTypeFilterItem s_entityTypeFilterNoneItem = 
                new EntityDataSourceEntityTypeFilterItem(Strings.Wizard_DataSelectionPanel_NoEntityTypeFilter);
        #endregion

        #region Private readonly fields 
        private readonly EntityDataSourceDataSelectionPanel _panel;
        private readonly EntityDataSourceDesignerHelper _helper; 
        #endregion 

        #region Private fields for temporary storage of property values 
        private readonly EntityDataSourceState _entityDataSourceState;
        private List _entitySetNames;
        private EntityDataSourceEntitySetNameItem _selectedEntitySetName;
        private List _entityTypeFilters; 
        private EntityDataSourceEntityTypeFilterItem _selectedEntityTypeFilter;
 
        #region Select views 
        // The Data Selection wizard panel can display two kinds of views of the Select property:
        //     (1) Simple Select View: CheckedListBox with a list of available entity type properties 
        //     (2) Advanced Select View: TextBox that allows any statement to be entered (no validation)
        //
        // When either view is visible to the user, the fields shown below for that view should be non-null, and the fields
        // for the other view should be null. 

        // Simple Select View 
        // _selectedEntityTypeProperties contains a set of indexes of properties in _entityTypeProperties 
        private List _entityTypeProperties;
        private List _selectedEntityTypeProperties; 

        // Advanced Select View
        private string _select;
        #endregion 

        private bool _enableInsert; 
        private bool _enableUpdate; 
        private bool _enableDelete;
        private readonly EntityDataSourceWizardForm _wizardForm; 
        #endregion

        #region Constructors
        internal EntityDataSourceDataSelection(EntityDataSourceDataSelectionPanel panel, EntityDataSourceWizardForm wizard, EntityDataSourceDesignerHelper designerHelper, EntityDataSourceState entityDataSourceState) 
        {
            _panel = panel; 
            _panel.Register(this); 
            _helper = designerHelper;
 
            _entityDataSourceState = entityDataSourceState;
            _wizardForm = wizard;
        }
        #endregion 

        #region Events 
        // Event handler to process notifications when a DefaultContainerName is selected on the ObjectContext configuration panel 
        internal void ContainerNameChangedHandler(object sender, EntityDataSourceContainerNameItem newContainerName)
        { 
            // Load the entity sets for this container, don't select anything initially in the list
            LoadEntitySetNames(newContainerName, null);

            // Reset the other controls that depend on the value of EntitySet 
            LoadEntityTypeFilters(null, null);
            LoadSelect(String.Empty); 
        } 
        #endregion
 
        #region Methods to manage temporary state and wizard contents
        // Used when the wizard is launched, to load existing property values from data source control
        internal void LoadState()
        { 
            LoadEntitySetNames(_helper.GetEntityContainerItem(_entityDataSourceState.DefaultContainerName), _entityDataSourceState.EntitySetName);
            LoadEntityTypeFilters(_selectedEntitySetName, _entityDataSourceState.EntityTypeFilter); 
            LoadSelect(_entityDataSourceState.Select); 
            LoadInsertUpdateDelete();
        } 

        // Save current wizard settings back to the EntityDataSourceState
        internal void SaveState()
        { 
            SaveEntitySetName();
            SaveEntityTypeFilter(); 
            SaveSelect(); 
            SaveInsertUpdateDelete();
        } 

        #region EntitySetName
        // Find the specified entitySetName in the list or add it if it's not there
        private EntityDataSourceEntitySetNameItem FindEntitySetName(string entitySetName) 
        {
            if (!String.IsNullOrEmpty(entitySetName)) 
            { 
                EntityDataSourceEntitySetNameItem entitySetToSelect = null;
                foreach (EntityDataSourceEntitySetNameItem entitySetNameItem in _entitySetNames) 
                {
                    // Ignore case here when searching the list for a matching item, but set the temporary state property to the
                    // correctly-cased version from metadata so that if the user clicks Finish, the correct one will be saved. This
                    // allows some flexibility the designer without preserving an incorrectly-cased value that could cause errors at runtime. 
                    if (String.Equals(entitySetNameItem.EntitySetName, entitySetName, StringComparison.OrdinalIgnoreCase))
                    { 
                        entitySetToSelect = entitySetNameItem; 
                    }
                } 

                // didn't find a matching entityset, so just create a placeholder for one using the specified name and add it to the list
                if (entitySetToSelect == null)
                { 
                    entitySetToSelect = new EntityDataSourceEntitySetNameItem(entitySetName);
                    _entitySetNames.Add(entitySetToSelect); 
                } 

                Debug.Assert(entitySetToSelect != null, "expected a non-null EntityDataSourceEntitySetNameItem"); 
                return entitySetToSelect;
            }

            return null; 
        }
 
        // Populates the EntitySetName combobox with all of the discoverable EntitySets for the specified container. 
        // If the specified entitySetName is not empty, it is added to the list and selected as the initial value
        // containerNameItem may not be backed by a real EntityContainer, in which case there is no way to look up the EntitySet in metadata 
        // devnote: This method should not automatically reset EntityTypeFilter and Select because it can be used to load the initial state
        //          for the form, in which case we need to preserve any values that are already set on the data source control.
        private void LoadEntitySetNames(EntityDataSourceContainerNameItem containerNameItem, string entitySetName)
        { 
            // If this is a container that we found in the project's metadata, get a list of EntitySets for that container
            if (containerNameItem != null && containerNameItem.EntityContainer != null) 
            { 
                _entitySetNames = _helper.GetEntitySets(containerNameItem.EntityContainer, false /*sortResults*/);
 
                // Try to find the specified entityset in list and add it if it isn't there
                _selectedEntitySetName = FindEntitySetName(entitySetName);
            }
            else 
            {
                // if this is an unknown container, there is no way to find a list of entitysets from metadata 
                // so just create a new list and placeholder for the specified entityset 
                _entitySetNames = new List();
                if (!String.IsNullOrEmpty(entitySetName)) 
                {
                    _selectedEntitySetName = new EntityDataSourceEntitySetNameItem(entitySetName);
                    _entitySetNames.Add(_selectedEntitySetName);
                } 
                else
                { 
                    _selectedEntitySetName = null; 
                }
            } 

            // Sort the list now, after we may have added one above
            _entitySetNames.Sort();
 
            // Update the controls
            _panel.SetEntitySetNames(_entitySetNames); 
            _panel.SetSelectedEntitySetName(_selectedEntitySetName); 
        }
 
        // Set EntitySetName in temporary storage
        internal void SelectEntitySetName(EntityDataSourceEntitySetNameItem selectedEntitySet)
        {
            _selectedEntitySetName = selectedEntitySet; 
            // Load the types for the selected EntitySet, don't select one initially
            LoadEntityTypeFilters(selectedEntitySet, null); 
            // Reinitialize the Select control with a list of properties, don't preserve any existing Select value 
            LoadSelect(String.Empty);
        } 

        private void SaveEntitySetName()
        {
            if (_selectedEntitySetName != null) 
            {
                _entityDataSourceState.EntitySetName = _selectedEntitySetName.EntitySetName; 
            } 
            else
            { 
                _entityDataSourceState.EntitySetName = String.Empty;
            }
        }
        #endregion 

        #region EntityTypeFilter 
        // Populate a list with the base type for the EntitySet plus all derived types, and a special entry to indicate no filter 
        // devnote: This method should not automatically reset Select because it can be used to load the initial state
        //          for the form, in which case we need to preserve any values that are already set on the data source control. 
        private void LoadEntityTypeFilters(EntityDataSourceEntitySetNameItem entitySetItem, string entityTypeFilter)
        {
            // If this is an EntitySet that we found in the project's metadata, get the type information
            if (entitySetItem != null && entitySetItem.EntitySet != null) 
            {
                _entityTypeFilters = _helper.GetEntityTypeFilters(entitySetItem.EntitySet.ElementType, false /*sortResults*/); 
                // add (None) to the beginning of the list 
                _entityTypeFilters.Insert(0, s_entityTypeFilterNoneItem);
 
                // Try to find the specified type in list and add it if it isn't there
                _selectedEntityTypeFilter = FindEntityTypeFilter(entityTypeFilter);
            }
            else 
            {
                // if this is an unknown EntitySet, there is no way to find a list of types from metadata 
                // so just create a new list and placeholder for the specified type 
                _entityTypeFilters = new List();
                _entityTypeFilters.Add(s_entityTypeFilterNoneItem); 

                if (!String.IsNullOrEmpty(entityTypeFilter))
                {
                    _selectedEntityTypeFilter = new EntityDataSourceEntityTypeFilterItem(entityTypeFilter); 
                    _entityTypeFilters.Add(_selectedEntityTypeFilter);
                } 
                else 
                {
                    _selectedEntityTypeFilter = s_entityTypeFilterNoneItem; 
                }
            }

            // Sort now after we might have added items above 
            _entityTypeFilters.Sort();
 
            // Update the controls 
            _panel.SetEntityTypeFilters(_entityTypeFilters);
            _panel.SetSelectedEntityTypeFilter(_selectedEntityTypeFilter); 
        }

        // Find the specified entityTypeFilter in the list and add it if it's not there
        private EntityDataSourceEntityTypeFilterItem FindEntityTypeFilter(string entityTypeFilter) 
        {
            if (!String.IsNullOrEmpty(entityTypeFilter)) 
            { 
                EntityDataSourceEntityTypeFilterItem typeToSelect = null;
                foreach (EntityDataSourceEntityTypeFilterItem entityTypeFilterItem in _entityTypeFilters) 
                {
                    // Ignore case here when searching the list for a matching item, but set the temporary state property to the
                    // correctly-cased version from metadata so that if the user clicks Finish, the correct one will be saved. This
                    // allows some flexibility the designer without preserving an incorrectly-cased value that could cause errors at runtime. 
                    if (String.Equals(entityTypeFilterItem.EntityTypeName, entityTypeFilter, StringComparison.OrdinalIgnoreCase))
                    { 
                        typeToSelect = entityTypeFilterItem; 
                    }
                } 

                // didn't find a matching type, so just create a placeholder item and add it to the list
                if (typeToSelect == null)
                { 
                    typeToSelect = new EntityDataSourceEntityTypeFilterItem(entityTypeFilter);
                    _entityTypeFilters.Add(typeToSelect); 
 
                }
 
                Debug.Assert(typeToSelect != null, "expected a non-null string for EntityTypeFilter");
                return typeToSelect;
            }
 
            return s_entityTypeFilterNoneItem;
        } 
 
        // Set EntityTypeFilter in temporary storage and load the Select property
        internal void SelectEntityTypeFilter(EntityDataSourceEntityTypeFilterItem selectedEntityTypeFilter) 
        {
            _selectedEntityTypeFilter = selectedEntityTypeFilter;
            // Reinitialize the Select control with a list of properties, don't preserve any existing Select value
            LoadSelect(String.Empty); 
        }
 
        private void SaveEntityTypeFilter() 
        {
            // If (None) is selected, it is the same as an empty string on the data source control 
            if (Object.ReferenceEquals(_selectedEntityTypeFilter, s_entityTypeFilterNoneItem))
            {
                _entityDataSourceState.EntityTypeFilter = String.Empty;
            } 
            else
            { 
                _entityDataSourceState.EntityTypeFilter = _selectedEntityTypeFilter.EntityTypeName; 
            }
        } 

        #endregion

        #region Select 
        // Load and parse the Select property
        private void LoadSelect(string select) 
        { 
            Debug.Assert(_selectedEntityTypeFilter != null, "_selectedEntityTypeFilter should never be null");
 
            System.Data.Metadata.Edm.EntityType entityType = null;

            // determine which EntityType to load properties for, based on the value selected for EntityTypeFilter
            if (Object.ReferenceEquals(_selectedEntityTypeFilter, s_entityTypeFilterNoneItem)) 
            {
                // If (None) is selected, use the base type for the EntitySet if available 
                if (_selectedEntitySetName != null && _selectedEntitySetName.EntitySet != null) 
                {
                    entityType = _selectedEntitySetName.EntitySet.ElementType; 
                }
                // else the EntitySet base type is not known
            }
            else 
            {
                entityType = _selectedEntityTypeFilter.EntityType; // could still be null if the type if not known in metadata 
            } 

            if (entityType != null) 
            {
                // this is a real type from metadata, load its properties
                _entityTypeProperties = _helper.GetEntityTypeProperties(entityType);
                // add the 'Select All (Entity Value)' placeholder at the beginning of the list 
                _entityTypeProperties.Insert(0, Strings.Wizard_DataSelectionPanel_SelectAllProperties);
 
                // parse the current value for the Select property to see if it can be displayed in the simple CheckedListBox view 
                if (TryParseSelect(select))
                { 
                    _select = null;

                    // Update the controls
                    _panel.SetEntityTypeProperties(_entityTypeProperties, _selectedEntityTypeProperties); 
                    UpdateInsertUpdateDeleteState();
                    return; 
                } 
                // else we failed to parse the select into entity type properties on the specified type, so just use the advanced select view
            } // else can't get a list of properties unless we have a known EntityType 


            // if we don't have a valid entity type or couldn't parse the incoming Select value, just display the advanced TextBox view
            _entityTypeProperties = null; 
            _selectedEntityTypeProperties = null;
            _select = select; 
 
            // Update the controls
            _panel.SetSelect(_select); 
            UpdateInsertUpdateDeleteState();
        }

        // Build a value for the Select property from the selected values in the CheckedListBox 
        // Value will be in the from "it.Property1, it.Property2, it.Property3"
        private string BuildSelect() 
        { 
            Debug.Assert(_selectedEntityTypeProperties != null && _selectedEntityTypeProperties.Count > 0, "expected non-null _selectedEntityTypeProperties with at least one value");
 
            // 'Select All (Entity Value)' is the same thing as an empty string for the property
            if (_selectedEntityTypeProperties[0] == 0)
            {
                Debug.Assert(_selectedEntityTypeProperties.Count == 1, "'Select All (Entity Value)' should be the only property selected"); 
                return String.Empty;
            } 
 
            StringBuilder selectProperties = new StringBuilder();
            bool addComma = false; 
            foreach (int propertyIndex in _selectedEntityTypeProperties)
            {
                if (addComma)
                { 
                    selectProperties.Append(", ");
                } 
                else 
                {
                    addComma = true; 
                }

                selectProperties.AppendFormat(CultureInfo.InvariantCulture, "{0}{1}", s_itKeyword, EscapePropertyName(_entityTypeProperties[propertyIndex]));
 
            }
            return selectProperties.ToString(); 
        } 

        private static string EscapePropertyName(string propertyName) 
        {
            return "[" + propertyName.Replace("]", "]]") + "]";
        }
 
        static string UnescapePropertyName(string name)
        { 
            if (name[0] == '[' && name[name.Length - 1] == ']') 
            {
                return name.Substring(1, name.Length - 2).Replace("]]", "]"); 
            }
            else
            {
                // else the property is not escaped at all or is not properly escaped. We can't parse it so just return. 
                return name;
            } 
        } 

        // Parses the current Select property on the data source to see if it matches a specific format that we can use to display the properties 
        // in the CheckedListBox in the simple select wizard view
        private bool TryParseSelect(string currentSelect)
        {
            bool parseSuccess = false; // gets set to true after the statement has been successfully parsed 
            if (!String.IsNullOrEmpty(currentSelect))
            { 
                // first try to split the string up into pieces divided by commas 
                // expects a format like the following: (extra spaces around the commas should work as well)
                //     "it.KnownPropertyName1, it.KnownPropertyName2, it.KnownPropertyName3" 
                string[] tokenizedSelect = currentSelect.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                bool foundUnknownProperty = false;
                List selectedProperties = new List(); 
                foreach (string token in tokenizedSelect)
                { 
                    string propertyName = token.Trim(); 

                    // Does the current property token start with "it."? 
                    if (ReadItKeyword(propertyName))
                    {
                        // Does the rest of the property token match a known property name for the selected EntityTypeFilter?
                        int propertyIndex = ReadPropertyName(propertyName.Substring(s_itKeyword.Length)); 
                        if (propertyIndex == -1)
                        { 
                            // the property was not known, so we can just stop looking 
                            foundUnknownProperty = true;
                            break; 
                        }
                        else
                        {
                            // this is a known property, so add its index to the list 
                            selectedProperties.Add(propertyIndex);
                        } 
                    } 
                    else
                    { 
                        // the property was not known, so we can just stop looking
                        foundUnknownProperty = true;
                        break;
                    } 
                }
                if (!foundUnknownProperty) 
                { 
                    // if we never found anything unknown, the current list of properties is what we'll use to fill in the CheckedListBox
                    _selectedEntityTypeProperties = selectedProperties; 
                    parseSuccess = true;
                }
                else
                { 
                    _selectedEntityTypeProperties = null;
                } 
            } 
            else
            { 
                // if Select is empty, we just want to add 'Select All (Entity Value)' to the list
                _selectedEntityTypeProperties = new List();
                _selectedEntityTypeProperties.Add(0);
                parseSuccess = true; 
            }
 
            return parseSuccess; 
        }
 
        // Determines if the specified propertyName starts with "it." (case-insensitive)
        private bool ReadItKeyword(string propertyName)
        {
            // will accept any casing of "it." here, although when the value is saved back to the property, it will be correctly lower-cased 
            return propertyName.StartsWith(s_itKeyword, StringComparison.OrdinalIgnoreCase);
        } 
 
        // Determines if the specified propertyName matches one of the known properties for the selected type
        private int ReadPropertyName(string propertyName) 
        {
            for (int propIndex = 0; propIndex < _entityTypeProperties.Count; propIndex++)
            {
                // Ignore case here when searching the list for a matching item, but set the temporary state property to the 
                // correctly-cased version from metadata so that if the user clicks Finish, the correct one will be saved. This
                // allows some flexibility the designer without preserving an incorrectly-cased value that could cause errors at runtime. 
 
                // Does the specified property name exactly match any of the properties for the selected EntityTypeFilter?
                if (String.Equals(UnescapePropertyName(propertyName), _entityTypeProperties[propIndex], StringComparison.OrdinalIgnoreCase)) 
                {
                    return propIndex;
                }
            } 

            return -1; 
        } 

        // Add the specified property to the list of selected entity properties used to build up the Select property 
        internal void SelectEntityProperty(int propertyIndex)
        {
            _selectedEntityTypeProperties.Add(propertyIndex);
        } 

        internal void ClearAllSelectedProperties() 
        { 
            _selectedEntityTypeProperties.Clear();
        } 

        // Remove specified entity property index from the selected list
        internal void DeselectEntityProperty(int propertyIndex)
        { 
            _selectedEntityTypeProperties.Remove(propertyIndex);
        } 
 
        // Set Select property to the specified string (used with advanced select view)
        internal void SelectAdvancedSelect(string select) 
        {
            _select = select;
        }
 
        private void SaveSelect()
        { 
            if (_select != null) 
            {
                _entityDataSourceState.Select = _select; 
            }
            else
            {
                Debug.Assert(_selectedEntityTypeProperties != null, "expected _entityTypeProperties to be non-null if _select is null"); 
                _entityDataSourceState.Select = BuildSelect();
            } 
        } 
        #endregion
 
        #region EnableInsertUpdateDelete
        // Load the initial values for EnableInsert/EnableUpdate/EnableDelete CheckBoxes
        private void LoadInsertUpdateDelete()
        { 
            SelectEnableInsert(_entityDataSourceState.EnableInsert);
            SelectEnableUpdate(_entityDataSourceState.EnableUpdate); 
            SelectEnableDelete(_entityDataSourceState.EnableDelete); 

            UpdateInsertUpdateDeleteState(); 
        }

        // Set EnableDelete in temporary storage
        internal void SelectEnableDelete(bool enableDelete) 
        {
            _enableDelete = enableDelete; 
        } 

        // Set EnableInsert in temporary storage 
        internal void SelectEnableInsert(bool enableInsert)
        {
            _enableInsert = enableInsert;
        } 

        // Set EnableUpdate in temporary storage 
        internal void SelectEnableUpdate(bool enableUpdate) 
        {
            _enableUpdate = enableUpdate; 
        }

        private void SaveInsertUpdateDelete()
        { 
            _entityDataSourceState.EnableInsert = _enableInsert;
            _entityDataSourceState.EnableUpdate = _enableUpdate; 
            _entityDataSourceState.EnableDelete = _enableDelete; 
        }
 
        /// 
        /// Update the panel control state based on the valued of enableInsert,
        /// enableUpdate, enableDelete, and the selectedEntityTypeProperties
        ///  
        internal void UpdateInsertUpdateDeleteState()
        { 
            // Set the checkbox state for the panel controls 
            _panel.SetEnableInsertUpdateDelete(_enableInsert, _enableUpdate, _enableDelete);
 
            // The InsertUpdateDelete panel should be enabled if:
            // 1. Insert, Update, or Delete is selected -OR-
            // 2. The EntitySelection has SelectAll checked
            bool enablePanel = (_enableInsert || _enableUpdate || _enableDelete || 
                        (_selectedEntityTypeProperties != null &&
                         _selectedEntityTypeProperties.Count == 1 && 
                         _selectedEntityTypeProperties[0] == 0)); 

            _panel.SetEnableInsertUpdateDeletePanel(enablePanel); 
        }
        #endregion
        #endregion
 
        #region Wizard button state management
        internal void UpdateWizardState() 
        { 
            // EntitySetName must be selected and a Select must be configured or must be the empty string
            _wizardForm.SetCanFinish(_selectedEntitySetName != null && (_select != null || _selectedEntityTypeProperties.Count > 0)); 
        }
        #endregion
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK