1. Михаил Сафонов
  2. DgvPopupFilter

Commits

Михаил Сафонов  committed b934e3b

init

  • Participants
  • Branches default

Comments (0)

Files changed (34)

File DgvFilterPopup.csproj

View file
  • Ignore whitespace
+ďťż<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.50727</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{4B9BE5FD-303E-4270-9C4D-FA3BDE6C34EB}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>DgvFilterPopup</RootNamespace>
+    <AssemblyName>DgvFilterPopup</AssemblyName>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <SccProjectName>&lt;Project Location In Database&gt;</SccProjectName>
+    <SccLocalPath>&lt;Local Binding Root of Project&gt;</SccLocalPath>
+    <SccAuxPath>&lt;Source Control Database&gt;</SccAuxPath>
+    <SccProvider>Mercurial Source Control Package</SccProvider>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Debug\DgvFilterPopup.XML</DocumentationFile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>
+    </DocumentationFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Design" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="FilterPopup\ColumnFilterEvent.cs" />
+    <Compile Include="FilterPopup\Extensions\DgvDateRangeColumnFilter.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FilterPopup\Extensions\DgvDateRangeColumnFilter.Designer.cs">
+      <DependentUpon>DgvDateRangeColumnFilter.cs</DependentUpon>
+    </Compile>
+    <Compile Include="FilterPopup\Extensions\DgvMonthYearColumnFilter.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FilterPopup\Extensions\DgvMonthYearColumnFilter.Designer.cs">
+      <DependentUpon>DgvMonthYearColumnFilter.cs</DependentUpon>
+    </Compile>
+    <Compile Include="FilterPopup\Extensions\DgvNumRangeColumnFilter.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FilterPopup\Extensions\DgvNumRangeColumnFilter.Designer.cs">
+      <DependentUpon>DgvNumRangeColumnFilter.cs</DependentUpon>
+    </Compile>
+    <Compile Include="FilterPopup\Implementations\DgvDateColumnFilter.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FilterPopup\Implementations\DgvDateColumnFilter.Designer.cs">
+      <DependentUpon>DgvDateColumnFilter.cs</DependentUpon>
+    </Compile>
+    <Compile Include="FilterPopup\Implementations\DgvCheckBoxColumnFilter.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FilterPopup\Implementations\DgvCheckBoxColumnFilter.Designer.cs">
+      <DependentUpon>DgvCheckBoxColumnFilter.cs</DependentUpon>
+    </Compile>
+    <Compile Include="FilterPopup\Implementations\DgvComboBoxColumnFilter.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FilterPopup\Implementations\DgvComboBoxColumnFilter.Designer.cs">
+      <DependentUpon>DgvComboBoxColumnFilter.cs</DependentUpon>
+    </Compile>
+    <Compile Include="FilterPopup\DgvBaseFilterHost.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FilterPopup\DgvFilterManager.cs" />
+    <Compile Include="FilterPopup\DgvBaseColumnFilter.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FilterPopup\Implementations\DgvFilterHost.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FilterPopup\Implementations\DgvFilterHost.Designer.cs">
+      <DependentUpon>DgvFilterHost.cs</DependentUpon>
+    </Compile>
+    <Compile Include="FilterPopup\Implementations\DgvTextBoxColumnFilter.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FilterPopup\Implementations\DgvTextBoxColumnFilter.Designer.cs">
+      <DependentUpon>DgvTextBoxColumnFilter.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="FilterPopup\Extensions\DgvDateRangeColumnFilter.resx">
+      <DependentUpon>DgvDateRangeColumnFilter.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="FilterPopup\Extensions\DgvMonthYearColumnFilter.resx">
+      <SubType>Designer</SubType>
+      <DependentUpon>DgvMonthYearColumnFilter.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="FilterPopup\Extensions\DgvNumRangeColumnFilter.resx">
+      <DependentUpon>DgvNumRangeColumnFilter.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="FilterPopup\Implementations\DgvDateColumnFilter.resx">
+      <DependentUpon>DgvDateColumnFilter.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="FilterPopup\Implementations\DgvCheckBoxColumnFilter.resx">
+      <DependentUpon>DgvCheckBoxColumnFilter.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="FilterPopup\Implementations\DgvComboBoxColumnFilter.resx">
+      <DependentUpon>DgvComboBoxColumnFilter.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="FilterPopup\Implementations\DgvFilterHost.resx">
+      <DependentUpon>DgvFilterHost.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="FilterPopup\Implementations\DgvTextBoxColumnFilter.resx">
+      <SubType>Designer</SubType>
+      <DependentUpon>DgvTextBoxColumnFilter.cs</DependentUpon>
+    </EmbeddedResource>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Diagrams\DetailDiagram.cd" />
+    <None Include="Diagrams\BasicDiagram.cd" />
+    <None Include="Diagrams\Extensions.cd" />
+    <None Include="Diagrams\Implementations.cd" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

File Diagrams/BasicDiagram.cd

View file
  • Ignore whitespace
+ďťż<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram MajorVersion="1" MinorVersion="1">
+  <Font Name="Tahoma" Size="8.25" />
+  <Class Name="DgvFilterPopup.DgvFilterManager" Collapsed="true">
+    <Position X="2.5" Y="3.25" Width="2" />
+    <TypeIdentifier>
+      <FileName>FilterPopup\DgvFilterManager.cs</FileName>
+      <HashCode>EEAAIKAIABAAkgACCIhAIQAAAACABBCABgBABAIAABA=</HashCode>
+    </TypeIdentifier>
+    <ShowAsAssociation>
+      <Property Name="FilterHost" />
+      <Property Name="this[System.Int32]" />
+      <Property Name="this[System.String]" />
+    </ShowAsAssociation>
+    <Members>
+      <Field Name="mAutoCreateFilters" Hidden="true" />
+      <Field Name="mBaseFilter" Hidden="true" />
+      <Field Name="mBoundDataView" Hidden="true" />
+      <Field Name="mCurrentColumnIndex" Hidden="true" />
+      <Field Name="mDataGridView" Hidden="true" />
+      <Field Name="mFilterHost" Hidden="true" />
+      <Field Name="mFilterIsActive" Hidden="true" />
+      <Field Name="mFilterPicture" Hidden="true" />
+      <Property Name="this" Hidden="true" />
+    </Members>
+    <AssociationLine Name="FilterHost" Type="DgvFilterPopup.DgvBaseFilterHost">
+      <MemberNameLabel ManuallyPlaced="true" ManuallySized="true">
+        <Position X="-1.149" Y="0.318" Height="0.16" Width="0.994" />
+      </MemberNameLabel>
+    </AssociationLine>
+    <AssociationLine Name="this[System.Int32]" Type="DgvFilterPopup.DgvBaseColumnFilter">
+      <MemberNameLabel ManuallyPlaced="true">
+        <Position X="0.173" Y="0.289" />
+      </MemberNameLabel>
+    </AssociationLine>
+  </Class>
+  <Class Name="DgvFilterPopup.DgvBaseColumnFilter" Collapsed="true">
+    <Position X="1" Y="4.25" Width="1.75" />
+    <TypeIdentifier>
+      <FileName>FilterPopup\DgvBaseColumnFilter.cs</FileName>
+      <HashCode>FQAAAgIBAAKAAhAJIBBqAFAAAAAgAMw0AEECAAgAAAA=</HashCode>
+    </TypeIdentifier>
+    <ShowAsAssociation>
+      <Property Name="FilterHost" />
+    </ShowAsAssociation>
+    <Members>
+      <Field Name="mActive" Hidden="true" />
+      <Field Name="mBoundDataView" Hidden="true" />
+      <Field Name="mColumnDataType" Hidden="true" />
+      <Field Name="mDataGridViewColumn" Hidden="true" />
+      <Field Name="mFilterApplySoon" Hidden="true" />
+      <Field Name="mFilterCaption" Hidden="true" />
+      <Field Name="mFilterExpression" Hidden="true" />
+      <Field Name="mFilterHost" Hidden="true" />
+      <Field Name="mFilterManager" Hidden="true" />
+      <Field Name="mHFilterAlignment" Hidden="true" />
+      <Field Name="mOriginalDataGridViewColumnHeaderText" Hidden="true" />
+      <Field Name="mVFilterAlignment" Hidden="true" />
+    </Members>
+    <Compartments>
+      <Compartment Name="Fields" Collapsed="true" />
+    </Compartments>
+    <AssociationLine Name="FilterHost" Type="DgvFilterPopup.DgvBaseFilterHost">
+      <MemberNameLabel ManuallyPlaced="true">
+        <Position X="0.402" Y="0.039" />
+      </MemberNameLabel>
+    </AssociationLine>
+  </Class>
+  <Class Name="DgvFilterPopup.DgvBaseFilterHost" Collapsed="true">
+    <Position X="4" Y="4.25" Width="2" />
+    <TypeIdentifier>
+      <FileName>FilterPopup\DgvBaseFilterHost.cs</FileName>
+      <HashCode>JBAAAQAAABBBBBUAAAACAAAAAAAACMAAAAAAAAAAAAA=</HashCode>
+    </TypeIdentifier>
+    <ShowAsAssociation>
+      <Property Name="CurrentColumnFilter" />
+    </ShowAsAssociation>
+    <Members>
+      <Field Name="mCurrentColumnFilter" Hidden="true" />
+      <Field Name="mFilterManager" Hidden="true" />
+      <Field Name="mPopup" Hidden="true" />
+      <Field Name="mSizeDifference" Hidden="true" />
+    </Members>
+    <AssociationLine Name="CurrentColumnFilter" Type="DgvFilterPopup.DgvBaseColumnFilter" FixedFromPoint="true">
+      <Path>
+        <Point X="4" Y="4.812" />
+        <Point X="2.75" Y="4.812" />
+      </Path>
+      <MemberNameLabel ManuallyPlaced="true">
+        <Position X="0.675" Y="-0.328" />
+      </MemberNameLabel>
+    </AssociationLine>
+  </Class>
+</ClassDiagram>

File Diagrams/DetailDiagram.cd

View file
  • Ignore whitespace
+ďťż<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram MajorVersion="1" MinorVersion="1">
+  <Font Name="Tahoma" Size="8.25" />
+  <Class Name="DgvFilterPopup.DgvFilterManager">
+    <Position X="3.5" Y="1.75" Width="2" />
+    <TypeIdentifier>
+      <FileName>FilterPopup\DgvFilterManager.cs</FileName>
+      <HashCode>EEAAIKAIABAAkgACCIhAIQAAAACADBCABgBABAIAABA=</HashCode>
+    </TypeIdentifier>
+    <ShowAsAssociation>
+      <Property Name="FilterHost" />
+      <Property Name="this[System.Int32]" />
+      <Property Name="this[System.String]" />
+    </ShowAsAssociation>
+    <Members>
+      <Method Name="CreateColumnFilter" Hidden="true" />
+      <Method Name="FindDataView" Hidden="true" />
+      <Field Name="mAutoCreateFilters" Hidden="true" />
+      <Field Name="mBaseFilter" Hidden="true" />
+      <Field Name="mBoundDataView" Hidden="true" />
+      <Field Name="mColumnFilterArray" Hidden="true" />
+      <Field Name="mCurrentColumnIndex" Hidden="true" />
+      <Field Name="mDataGridView" Hidden="true" />
+      <Method Name="mDataGridView_CellPainting" Hidden="true" />
+      <Method Name="mDataGridView_ColumnAdded" Hidden="true" />
+      <Method Name="mDataGridView_ColumnRemoved" Hidden="true" />
+      <Field Name="mFilterHost" Hidden="true" />
+      <Field Name="mFilterIsActive" Hidden="true" />
+      <Field Name="mFilterPicture" Hidden="true" />
+      <Method Name="Popup_Closed" Hidden="true" />
+      <Property Name="this" Hidden="true" />
+    </Members>
+    <AssociationLine Name="FilterHost" Type="DgvFilterPopup.DgvBaseFilterHost">
+      <MemberNameLabel ManuallyPlaced="true">
+        <Position X="0.216" Y="0.068" />
+      </MemberNameLabel>
+    </AssociationLine>
+    <AssociationLine Name="this[System.String]" Type="DgvFilterPopup.DgvBaseColumnFilter">
+      <MemberNameLabel ManuallyPlaced="true">
+        <Position X="0.204" Y="0.06" />
+      </MemberNameLabel>
+    </AssociationLine>
+  </Class>
+  <Class Name="DgvFilterPopup.DgvBaseColumnFilter">
+    <Position X="6.25" Y="1.75" Width="1.75" />
+    <TypeIdentifier>
+      <FileName>FilterPopup\DgvBaseColumnFilter.cs</FileName>
+      <HashCode>FQAAAgIBAAKAAhAJIBBqAFAAAAAgAMw0AEECAAgAAAA=</HashCode>
+    </TypeIdentifier>
+    <ShowAsAssociation>
+      <Property Name="FilterHost" />
+    </ShowAsAssociation>
+    <Members>
+      <Field Name="mActive" Hidden="true" />
+      <Field Name="mBoundDataView" Hidden="true" />
+      <Field Name="mColumnDataType" Hidden="true" />
+      <Field Name="mDataGridViewColumn" Hidden="true" />
+      <Field Name="mFilterApplySoon" Hidden="true" />
+      <Field Name="mFilterCaption" Hidden="true" />
+      <Field Name="mFilterExpression" Hidden="true" />
+      <Field Name="mFilterHost" Hidden="true" />
+      <Field Name="mFilterManager" Hidden="true" />
+      <Field Name="mHFilterAlignment" Hidden="true" />
+      <Field Name="mOriginalDataGridViewColumnHeaderText" Hidden="true" />
+      <Field Name="mVFilterAlignment" Hidden="true" />
+    </Members>
+    <Compartments>
+      <Compartment Name="Fields" Collapsed="true" />
+    </Compartments>
+    <AssociationLine Name="FilterHost" Type="DgvFilterPopup.DgvBaseFilterHost">
+      <MemberNameLabel ManuallyPlaced="true" ManuallySized="true">
+        <Position X="-3.963" Y="1.029" Height="0.16" Width="0.93" />
+      </MemberNameLabel>
+    </AssociationLine>
+  </Class>
+  <Class Name="DgvFilterPopup.DgvBaseFilterHost">
+    <Position X="0.5" Y="2" Width="2" />
+    <TypeIdentifier>
+      <FileName>FilterPopup\DgvBaseFilterHost.cs</FileName>
+      <HashCode>JBAAAQAAABBBBBUAAAACAAAAAAAACMAAAAAAAAAAAAA=</HashCode>
+    </TypeIdentifier>
+    <ShowAsAssociation>
+      <Property Name="CurrentColumnFilter" />
+    </ShowAsAssociation>
+    <Members>
+      <Field Name="mCurrentColumnFilter" Hidden="true" />
+      <Field Name="mFilterManager" Hidden="true" />
+      <Field Name="mPopup" Hidden="true" />
+      <Field Name="mSizeDifference" Hidden="true" />
+      <Method Name="onDropDown" Hidden="true" />
+      <Method Name="onDropDownClosed" Hidden="true" />
+    </Members>
+    <AssociationLine Name="CurrentColumnFilter" Type="DgvFilterPopup.DgvBaseColumnFilter" ManuallyRouted="true" FixedFromPoint="true" FixedToPoint="true">
+      <Path>
+        <Point X="1.5" Y="4.851" />
+        <Point X="1.5" Y="6.948" />
+        <Point X="6.812" Y="6.948" />
+        <Point X="6.812" Y="6.573" />
+      </Path>
+      <MemberNameLabel ManuallyPlaced="true">
+        <Position X="3.914" Y="0.141" />
+      </MemberNameLabel>
+    </AssociationLine>
+  </Class>
+</ClassDiagram>

File Diagrams/Extensions.cd

View file
  • Ignore whitespace
+ďťż<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram MajorVersion="1" MinorVersion="1">
+  <Font Name="Tahoma" Size="8.25" />
+  <Class Name="DgvFilterPopup.DgvDateRangeColumnFilter" Collapsed="true">
+    <Position X="1.5" Y="2" Width="2.25" />
+    <TypeIdentifier>
+      <FileName>FilterPopup\Extensions\DgvDateRangeColumnFilter.cs</FileName>
+      <HashCode>AAAAAAAAAHAAAAAAAACAIAACACAAAAAEAAAAABgCgAA=</HashCode>
+    </TypeIdentifier>
+    <InheritanceLine Type="DgvFilterPopup.DgvBaseColumnFilter" FixedFromPoint="true" FixedToPoint="true">
+      <Path>
+        <Point X="3.625" Y="1.63" />
+        <Point X="3.625" Y="2" />
+      </Path>
+    </InheritanceLine>
+  </Class>
+  <Class Name="DgvFilterPopup.DgvMonthYearColumnFilter" Collapsed="true">
+    <Position X="1.5" Y="2.75" Width="2.25" />
+    <TypeIdentifier>
+      <FileName>FilterPopup\Extensions\DgvMonthYearColumnFilter.cs</FileName>
+      <HashCode>AAAAACIAAGAAAAAAAADAAAACIAAAAiCEAQAABAgAAAQ=</HashCode>
+    </TypeIdentifier>
+    <InheritanceLine Type="DgvFilterPopup.DgvBaseColumnFilter" ManuallyRouted="true" FixedFromPoint="true">
+      <Path>
+        <Point X="3.938" Y="1.63" />
+        <Point X="3.938" Y="3.065" />
+        <Point X="3.75" Y="3.065" />
+      </Path>
+    </InheritanceLine>
+  </Class>
+  <Class Name="DgvFilterPopup.DgvNumRangeColumnFilter" Collapsed="true">
+    <Position X="1.5" Y="3.5" Width="2.25" />
+    <TypeIdentifier>
+      <FileName>FilterPopup\Extensions\DgvNumRangeColumnFilter.cs</FileName>
+      <HashCode>AAAAAAAAAHEAAAAAAACAAAACAAAAAEAEAABAABgBAAA=</HashCode>
+    </TypeIdentifier>
+    <InheritanceLine Type="DgvFilterPopup.DgvBaseColumnFilter" ManuallyRouted="true" FixedFromPoint="true" FixedToPoint="true">
+      <Path>
+        <Point X="4.167" Y="1.63" />
+        <Point X="4.167" Y="3.812" />
+        <Point X="3.75" Y="3.812" />
+      </Path>
+    </InheritanceLine>
+  </Class>
+  <Class Name="DgvFilterPopup.DgvBaseColumnFilter" Collapsed="true">
+    <Position X="2.5" Y="1" Width="2" />
+    <TypeIdentifier>
+      <FileName>FilterPopup\DgvBaseColumnFilter.cs</FileName>
+      <HashCode>FQAAAgIBAAKAAhAJIBBqAFAAAAAgAMw0AEECAAgAAAA=</HashCode>
+    </TypeIdentifier>
+  </Class>
+</ClassDiagram>

File Diagrams/Implementations.cd

View file
  • Ignore whitespace
+ďťż<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram MajorVersion="1" MinorVersion="1">
+  <Font Name="Tahoma" Size="8.25" />
+  <Class Name="DgvFilterPopup.DgvBaseFilterHost" Collapsed="true">
+    <Position X="1" Y="4.25" Width="1.5" />
+    <TypeIdentifier>
+      <FileName>FilterPopup\DgvBaseFilterHost.cs</FileName>
+      <HashCode>JBAAAQAAABBBBBUAAAACAAAAAAAACMAAAAAAAAAAAAA=</HashCode>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="DgvFilterPopup.DgvBaseColumnFilter" Collapsed="true">
+    <Position X="1.75" Y="0.75" Width="2" />
+    <TypeIdentifier>
+      <FileName>FilterPopup\DgvBaseColumnFilter.cs</FileName>
+      <HashCode>FQAAAgIBAAKAAhAJIBBqAFAAAAAgAMw0AEECAAgAAAA=</HashCode>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="DgvFilterPopup.DgvCheckBoxColumnFilter" Collapsed="true">
+    <Position X="0.5" Y="2" Width="2" />
+    <TypeIdentifier>
+      <FileName>FilterPopup\Implementations\DgvCheckBoxColumnFilter.cs</FileName>
+      <HashCode>AAAAAQAAAHAAAAAAAACAAAACAAAAAAAEAAAAABgAAAE=</HashCode>
+    </TypeIdentifier>
+    <InheritanceLine Type="DgvFilterPopup.DgvBaseColumnFilter" FixedFromPoint="true" FixedToPoint="true">
+      <Path>
+        <Point X="1.75" Y="1" />
+        <Point X="1.375" Y="1" />
+        <Point X="1.375" Y="2" />
+      </Path>
+    </InheritanceLine>
+  </Class>
+  <Class Name="DgvFilterPopup.DgvComboBoxColumnFilter" Collapsed="true">
+    <Position X="0.5" Y="3" Width="2" />
+    <TypeIdentifier>
+      <FileName>FilterPopup\Implementations\DgvComboBoxColumnFilter.cs</FileName>
+      <HashCode>AAABEAAAAHAAAAAAAACAAAACAAAAAAAEAAAAABgAAAA=</HashCode>
+    </TypeIdentifier>
+    <InheritanceLine Type="DgvFilterPopup.DgvBaseColumnFilter" ManuallyRouted="true" FixedFromPoint="true" FixedToPoint="true">
+      <Path>
+        <Point X="2.625" Y="1.38" />
+        <Point X="2.625" Y="2.808" />
+        <Point X="2.062" Y="2.808" />
+        <Point X="2.062" Y="3" />
+      </Path>
+    </InheritanceLine>
+  </Class>
+  <Class Name="DgvFilterPopup.DgvDateColumnFilter" Collapsed="true">
+    <Position X="3" Y="2" Width="2" />
+    <TypeIdentifier>
+      <FileName>FilterPopup\Implementations\DgvDateColumnFilter.cs</FileName>
+      <HashCode>AAAAAAAAAHAAAAAAAACAAAACAAAAAAAEAAAAABgCgAA=</HashCode>
+    </TypeIdentifier>
+    <InheritanceLine Type="DgvFilterPopup.DgvBaseColumnFilter" ManuallyRouted="true" FixedFromPoint="true" FixedToPoint="true">
+      <Path>
+        <Point X="3.75" Y="1" />
+        <Point X="4.143" Y="1" />
+        <Point X="4.143" Y="2" />
+      </Path>
+    </InheritanceLine>
+  </Class>
+  <Class Name="DgvFilterPopup.DgvTextBoxColumnFilter" Collapsed="true">
+    <Position X="3" Y="3" Width="2" />
+    <TypeIdentifier>
+      <FileName>FilterPopup\Implementations\DgvTextBoxColumnFilter.cs</FileName>
+      <HashCode>AAAAAAAAAHAAAAAAAACAAAACAAAAAEAEAABAABgAAAA=</HashCode>
+    </TypeIdentifier>
+    <InheritanceLine Type="DgvFilterPopup.DgvBaseColumnFilter" ManuallyRouted="true" FixedFromPoint="true" FixedToPoint="true">
+      <Path>
+        <Point X="2.875" Y="1.38" />
+        <Point X="2.875" Y="2.808" />
+        <Point X="3.438" Y="2.808" />
+        <Point X="3.438" Y="3" />
+      </Path>
+    </InheritanceLine>
+  </Class>
+  <Class Name="DgvFilterPopup.DgvFilterHost" Collapsed="true">
+    <Position X="1" Y="5.25" Width="1.5" />
+    <TypeIdentifier>
+      <FileName>FilterPopup\Implementations\DgvFilterHost.cs</FileName>
+      <HashCode>AAAAAAAAACAAAAQAAECAAAAiAAECAgAgAAAAAQJAAAA=</HashCode>
+    </TypeIdentifier>
+  </Class>
+</ClassDiagram>

File FilterPopup/ColumnFilterEvent.cs

View file
  • Ignore whitespace
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Windows.Forms;
+
+namespace DgvFilterPopup {
+
+
+
+    /// <summary>
+    /// Represents the method that will handle an event related to a column filter.
+    /// </summary>
+    /// <param name="sender">The source of the event.</param>
+    /// <param name="e">The <see cref="ColumnFilterEventArgs"/> instance containing the event data.</param>
+    public delegate void ColumnFilterEventHandler(object sender, ColumnFilterEventArgs e);
+
+
+    /// <summary>
+    /// Provides data for a column filter event. 
+    /// </summary>
+    public class ColumnFilterEventArgs : EventArgs {
+
+
+        #region PRIVATE FIELDS
+                
+        private DataGridViewColumn mColumn;
+        private DgvBaseColumnFilter mColumnFilter;
+        private bool mHandled;
+
+
+        #endregion 
+        
+        
+        #region PROPERTIES 
+
+
+        /// <summary>
+        /// Gets the DataGridView column involved in the event.
+        /// </summary>
+        public DataGridViewColumn Column { get { return mColumn; }}
+
+
+        /// <summary>
+        /// Gets or sets the column filter instance.
+        /// </summary>
+        /// <value>A column filter instance.</value>
+        public DgvBaseColumnFilter ColumnFilter {
+            get { return mColumnFilter; }
+            set { mColumnFilter = value; }
+        }
+
+        /// <summary>
+        /// Gets or sets a value indicating whether this <see cref="ColumnFilterEventArgs"/> is handled.
+        /// </summary>
+        /// <value><c>true</c> if handled; otherwise, <c>false</c>.</value>
+        public bool Handled {
+            get { return mHandled; }
+            set { mHandled = value; }
+        }
+
+        #endregion
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ColumnFilterEventArgs"/> class.
+        /// </summary>
+        /// <param name="Column">The DstaGridView column.</param>
+        /// <param name="ColumnFilter">The column filter instance.</param>
+        public ColumnFilterEventArgs(DataGridViewColumn Column, DgvBaseColumnFilter ColumnFilter) {
+            this.mColumn = Column;
+            this.mColumnFilter = ColumnFilter;
+            this.mHandled = Handled;
+        }
+    }
+}

File FilterPopup/DgvBaseColumnFilter.cs

View file
  • Ignore whitespace
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Windows.Forms;
+using System.Globalization;
+using System.ComponentModel;
+using System.Data;
+
+namespace DgvFilterPopup {
+
+    /// <summary>
+    /// Specifies how the <i>column filter</i> control is horizontally aligned inside the <i>filter host</i>.
+    /// </summary>
+    public enum HFilterAlignment { Top, Bottom, Middle }
+
+
+    /// <summary>
+    /// Specifies how the <i>column filter</i> control is vertically aligned inside the <i>filter host</i>.
+    /// </summary>
+    public enum VFilterAlignment { Left, Right, Center }
+
+
+    /// <summary>
+    /// The base class from which to derive effective <i>column filter</i> classes
+    /// </summary>
+    /// <remarks>
+    /// The purpose of a <i>column filter</i> control is to contain visual elements allowing the end user to construct a filter.
+    /// When inheriting from it, you can work just like creating any other user control. 
+    /// This class is a derivation of <b>UserControl</b> and provide functionalities to 
+    /// cooperate with DgvFilterManager. 
+    /// <para>
+    /// NOTE: 
+    /// This class must be intended as an abstract class. However, declaring it as abstract,
+    /// would generate errors whitin the designer when designing derived classes.
+    /// </para>
+    /// <para>
+    /// You should override <see cref="DgvBaseColumnFilter.OnFilterExpressionBuilding"/> to provide a filter expression construction 
+    /// logic and to set the values of the <see cref="DgvBaseColumnFilter.FilterExpression"/> and <see cref="DgvBaseColumnFilter.FilterCaption"/> properties. 
+    /// </para>
+    /// </remarks>      
+    public class DgvBaseColumnFilter : UserControl {
+
+        #region EVENTS
+
+        /// <summary>
+        /// Occurs before the filter expression is about to be built.
+        /// </summary>
+        public event CancelEventHandler FilterExpressionBuilding;
+
+
+        /// <summary>
+        /// Occurs when the filter column is about to be initialized.
+        /// </summary>
+        public event CancelEventHandler FilterInitializing;
+
+        #endregion
+
+
+        #region PRIVATE FIELDS
+
+        private VFilterAlignment mVFilterAlignment = VFilterAlignment.Center;
+        private HFilterAlignment mHFilterAlignment = HFilterAlignment.Middle;
+        private DgvBaseFilterHost mFilterHost;
+        private DgvFilterManager mFilterManager;
+        private DataGridViewColumn mDataGridViewColumn;
+        private DataView mBoundDataView;
+        private Type mColumnDataType;
+        private string mOriginalDataGridViewColumnHeaderText;
+        private bool mActive;
+        private bool mFilterApplySoon = true;
+
+        private string mFilterExpression = "";
+        private string mFilterCaption = "";
+
+        #endregion
+
+
+        #region PROPERTIES
+
+
+        /// <summary>
+        /// Gets or sets a value indicating whether filter apply soon after a user performs some changes.
+        /// </summary>
+        /// <value><c>true</c> (default) if to apply soon; otherwise, <c>false</c>.</value>
+        public bool FilterApplySoon {
+            get { return mFilterApplySoon; }
+            set { mFilterApplySoon = value; }
+        }
+
+        /// <summary>
+        /// Gets and sets the filter expression.
+        /// </summary>
+        /// <remarks>
+        /// It's the filter expression on the column. Its value is used by the <see cref="DgvFilterManager"/> to build the whole filter expression.
+        /// In inherited class, set its value in the override of <see cref="DgvBaseColumnFilter.OnFilterExpressionBuilding"/>.
+        /// The filter expression must follow the rules of the DataView <see cref="System.Data.DataView.RowFilter"/> property.
+        /// </remarks>
+        public string FilterExpression {
+            get { return mFilterExpression; }
+            set { mFilterExpression = value; }
+        }
+
+        /// <summary>
+        /// Gets and sets the caption to show in the column header when the filter is active.
+        /// </summary>
+        /// <remarks>
+        /// Represents the caption to show in the column header when the filter is active.
+        /// In inherited class, set its value in the override of <see cref="DgvBaseColumnFilter.OnFilterExpressionBuilding"/>.
+        /// </remarks>
+        public string FilterCaption { 
+            get { return ( (mActive && mFilterExpression!="") ? mFilterCaption : mOriginalDataGridViewColumnHeaderText) ; }
+            set { mFilterCaption = value; }
+        }
+
+
+        /// <summary>
+        /// Gets or sets a value indicating whether the filter is active.
+        /// </summary>
+        /// <value><c>true</c> if active; otherwise, <c>false</c>.</value>
+        public bool Active {
+          get { return (mActive); }
+          set { mActive = value; }
+        }
+
+        /// <summary>
+        /// Specifies how the <i>column filter</i> control is horizontally aligned inside the <i>filter host</i>.
+        /// </summary>
+        public HFilterAlignment HFilterAlignment {
+            get { return mHFilterAlignment; }
+            set { mHFilterAlignment = value; 
+            }
+        }
+
+
+        /// <summary>
+        /// Specifies how the <i>column filter</i> control is vertically aligned inside the <i>filter host</i>.
+        /// </summary>
+        public VFilterAlignment VFilterAlignment {
+            get { return mVFilterAlignment; }
+            set { mVFilterAlignment = value; }
+        }
+
+
+
+        /// <summary>
+        /// Gets the <b>DataView</b> acting as the data source of the <b>DataGridView</b> to which this <i>column filter</i> is applied.
+        /// </summary>
+        public DataView BoundDataView { get { return mBoundDataView; }}
+
+
+        /// <summary>
+        /// Gets the <i>filter host</i> control in which this <i>column filter</i> is shown.
+        /// </summary>
+        public DgvBaseFilterHost FilterHost { get { return mFilterHost; }}
+
+
+        /// <summary>
+        /// Gets the <i>filter manager</i>.
+        /// </summary>
+        public DgvFilterManager FilterManager { get { return mFilterManager; }}
+
+
+        /// <summary>
+        /// Gets the <b>DataGridView</b> column to which this <i>column filter</i> is applied.
+        /// </summary>
+        /// <value>The data grid view column.</value>
+        public DataGridViewColumn DataGridViewColumn { get { return mDataGridViewColumn; }}
+
+
+        /// <summary>
+        /// Gets the type of the data bound to the <b>DataGridView</b> column.
+        /// </summary>
+        public Type ColumnDataType { get { return mColumnDataType; }}
+
+
+
+        /// <summary>
+        /// Gets the original <b>DataGridView</b> column header text.
+        /// </summary>
+        public string OriginalDataGridViewColumnHeaderText { get { return mOriginalDataGridViewColumnHeaderText; } }
+
+
+        #endregion
+
+
+        #region FILTER INITIALIZATION, EXPRESSION BUILDING, EVENT MANAGING
+
+        /// <summary>
+        /// Called by the <i>filter manager</i>, inits the <i>column filter</i> and raises the FilterInitializing event.
+        /// </summary>
+        /// <param name="FilterManager">The <i>filter manager</i>.</param>
+        /// <param name="FilterHost">The filter host.</param>
+        /// <param name="gridColumn">The DataGridView column.</param>
+        /// <param name="boundDataView">The bound data view.</param>
+        public void Init(DgvFilterManager FilterManager, DgvBaseFilterHost FilterHost, DataGridViewColumn gridColumn,DataView boundDataView){
+            this.mFilterManager = FilterManager;
+            this.mFilterHost = FilterHost;
+            this.mDataGridViewColumn = gridColumn;
+            this.mBoundDataView = boundDataView;
+            this.mOriginalDataGridViewColumnHeaderText = gridColumn.HeaderText;
+            if (gridColumn.DataPropertyName != "")
+                this.mColumnDataType = boundDataView.Table.Columns[gridColumn.DataPropertyName].DataType;
+            else
+                this.mColumnDataType = typeof(string);
+            FilterHost.FilterClientArea.Controls.Add(this);
+            FilterHost.Location = new System.Drawing.Point(0, 0);
+            this.Visible = false;
+            CancelEventArgs e = new CancelEventArgs(false);
+            OnFilterInitializing(this, e);
+        }
+
+        /// <summary>
+        /// Raises the <see cref="DgvBaseColumnFilter.FilterInitializing"/> event
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.ComponentModel.CancelEventArgs"/> instance containing the event data.</param>
+        /// <remarks>
+        /// When this <i>column filter</i> control is added to the <i>column filters</i> array of the <i>filter manager</i>, 
+        /// the latter calls the <see cref="DgvBaseColumnFilter.Init"/> method which, in turn, calls this method. 
+        /// You can ovverride this method to provide initialization code. 
+        /// </remarks>
+        protected virtual void OnFilterInitializing(object sender, CancelEventArgs e) {
+            // Ovverride to add custom init code
+            if (FilterInitializing != null) FilterInitializing(sender, e);
+        }
+
+        /// <summary>
+        /// Forces the rebuilt of filter expression
+        /// </summary>
+        /// <remarks>
+        /// This method is called by <see cref="DgvFilterManager"/> when popup is closed, to 
+        /// force recreation of the filter expression. 
+        /// </remarks>
+        public void FilterExpressionBuild() {
+            CancelEventArgs e = new CancelEventArgs(false);
+            OnFilterExpressionBuilding(this,e);
+        }
+
+        /// <summary>
+        /// Raises the <see cref="DgvBaseColumnFilter.FilterExpressionBuilding"/> event
+        /// </summary>
+        /// <param name="sender">The event source.</param>
+        /// <param name="e">The <see cref="System.ComponentModel.CancelEventArgs"/> instance containing the event data.</param>
+        /// <remarks>
+        /// Override <b>OnFilterExpressionBuilding</b> to provide a filter expression construction 
+        /// logic and to set the values of the <see cref="DgvBaseColumnFilter.FilterExpression"/> and <see cref="DgvBaseColumnFilter.FilterCaption"/> properties.
+        /// The <see cref="DgvFilterManager"/> will use these properties in constructing the whole filter expression and to change the header text of the filtered column.
+        /// </remarks>
+        protected virtual void OnFilterExpressionBuilding(object sender,CancelEventArgs e) {
+            if (FilterExpressionBuilding != null) FilterExpressionBuilding(sender, e);
+        }
+
+
+
+        #endregion
+
+
+        #region HELPERS
+
+        /// <summary>
+        /// Escapes a string to be suitable for filter expression.
+        /// </summary>
+        /// <param name="s">The string to escape.</param>
+        /// <returns>The escaped string</returns>
+        public static string StringEscape(string s){
+            char[] sarray = s.ToCharArray();
+            StringBuilder sb = new StringBuilder(s.Length * 2);
+            foreach (char c in sarray) {
+                switch (c){
+                    case '%': case '*': case '[': case ']':
+                        sb.Append("[" + c + "]");
+                        break;
+                    case '\'':
+                        sb.Append("''");
+                        break;
+                    default:
+                        sb.Append(c);
+                        break;
+                }
+            }
+            return sb.ToString();
+        }
+
+        /// <summary>
+        /// Returns the string representation of the passed value, based on target type.
+        /// </summary>
+        /// <param name="value">The value to be formatted.</param>
+        /// <param name="targetType">The target type.</param>
+        /// <returns>The string representation of the passed value</returns>
+        public static string FormatValue(object value,Type targetType){
+            if (targetType == typeof(string)) return "'" + value.ToString() + "'";
+            try {
+                value = Convert.ChangeType(value, targetType);
+            } catch { return ""; }
+
+            if (targetType == typeof(bool)) return ((bool)value) ? "1" : "0";
+            if (targetType == typeof(DateTime)) return "'" + ((DateTime)value).ToString("yyyy'-'MM'-'dd") +"'";
+            //Numeric types
+            return ((IFormattable)value).ToString(null, NumberFormatInfo.InvariantInfo);
+        }
+
+        /// <summary>
+        /// Returns a null condition string to be used in filter expression.
+        /// </summary>
+        /// <param name="DataColumnName">Name of the data column.</param>
+        /// <returns>A string to be used in the filter expression representing a null condition</returns>
+        public static string GetNullCondition (string DataColumnName){
+            return "ISNULL(CONVERT(" + DataColumnName+ ",'System.String'),'NULLVALUE') = 'NULLVALUE'";
+        }
+
+        /// <summary>
+        /// Returns a not null condition string to be used in filter expression.
+        /// </summary>
+        /// <param name="DataColumnName">Name of the data column.</param>
+        /// <returns>A string to be used in the filter expression representing a not null condition</returns>
+        public static string GetNotNullCondition (string DataColumnName){
+            return "ISNULL(CONVERT(" + DataColumnName+ ",'System.String'),'NULLVALUE') <> 'NULLVALUE'";
+        }
+
+        #endregion
+
+    }
+}

File FilterPopup/DgvBaseFilterHost.cs

View file
  • Ignore whitespace
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Windows.Forms;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+
+namespace DgvFilterPopup {
+
+
+    /// <summary>
+    /// The base class from which to derive effective <i>filter host</i> controls
+    /// </summary>
+    /// <remarks>
+    /// The purpose of the <i>filter host</i> control is to show a popup near a right-clicked column and to 
+    /// host child <i>column filter</i> controls. 
+    /// When the popup is shown, only the <i>column filter</i> control related to right-clicked column
+    /// is visibile. 
+    /// <b>DgvBaseFilterHost</b> is a derivation of <b>UserControl</b> and provide functionalities to 
+    /// cooperate with <see cref="DgvFilterManager"/>.  
+    /// <para>
+    /// NOTE: 
+    /// This class must be intended as an abstract class. However, declaring it as abstract,
+    /// would generate errors whitin the designer when designing derived classes.
+    /// </para>
+    /// <para>
+    /// In your derivation, you have to provide a host area (such as a panel) and ovverride the 
+    /// <see cref="DgvBaseFilterHost.FilterClientArea"/> to return it. Also, create visual elements 
+    /// for <i>remove filter</i>, <i>remove all filters</i>, <i>apply filter</i> and use the 
+    /// <b>DgvFilterManager</b> methods <see cref="DgvFilterManager.ActivateFilter(bool)"/> and 
+    /// <see cref="DgvFilterManager.ActivateAllFilters "/>. 
+    /// </para>
+    /// </remarks>
+    /// <example>
+    /// <code>
+    ///public partial class DgvFilterHost : DgvBaseFilterHost {
+    ///
+    ///    public DgvFilterHost() {
+    ///        InitializeComponent();
+    ///        this.CurrentColumnFilterChanged += new EventHandler(DgvFilterHost_CurrentColumnFilterChanged);
+    ///    }
+    /// 
+    ///    void DgvFilterHost_CurrentColumnFilterChanged(object sender, EventArgs e) {
+    ///        lblColumnName.Text = CurrentColumnFilter.OriginalDataGridViewColumnHeaderText;
+    ///    }
+    /// 
+    ///    public override Control FilterClientArea {
+    ///        get {
+    ///            return this.panelFilterArea;
+    ///        }
+    ///    }
+    /// 
+    ///    private void tsOK_Click(object sender, EventArgs e) {
+    ///        FilterManager.ActivateFilter(true);
+    ///        this.Popup.Close();
+    ///    }
+    /// 
+    ///    private void tsRemove_Click(object sender, EventArgs e) {
+    ///        FilterManager.ActivateFilter(false);
+    ///        this.Popup.Close();
+    ///    }
+    /// 
+    ///    private void tsRemoveAll_Click(object sender, EventArgs e) {
+    ///        FilterManager.ActivateAllFilters(false);
+    ///        this.Popup.Close();
+    ///    }
+    /// 
+    ///}
+    /// </code>
+    /// </example>
+    public class DgvBaseFilterHost : UserControl {
+
+        #region EVENTS
+
+        /// <summary>
+        /// Occurs when the current visible <i>column filter</i> is changed.
+        /// </summary>
+        public event EventHandler CurrentColumnFilterChanged;
+
+        #endregion
+
+
+        #region PRIVATE FIELDS
+
+        private ToolStripDropDown mPopup;
+        private DgvFilterManager mFilterManager;
+        private DgvBaseColumnFilter mCurrentColumnFilter = null;
+        private Size mSizeDifference;
+
+        #endregion
+
+
+        #region PROPERTIES
+
+
+        /// <summary>
+        /// Return the effective area to which <i>column filters</i> will be added.
+        /// </summary>
+        public virtual Control FilterClientArea { get { return this; } }
+
+
+
+        /// <summary>
+        /// Gets the <b>ToolStripDropDown</b> object used to popup the <i>filter host</i>
+        /// </summary>
+        public ToolStripDropDown Popup
+        {
+          get { 
+              if (mPopup==null) {
+                mPopup = new ToolStripDropDown();
+                ToolStripControlHost ControlHost = new ToolStripControlHost(this);
+                ControlHost.Padding = Padding.Empty;
+                ControlHost.Margin = Padding.Empty;
+                ControlHost.AutoSize = false;
+                mPopup.Padding = Padding.Empty;
+                mPopup.Items.Add(ControlHost);
+                mPopup.Region = this.Region;
+              }
+              return mPopup; 
+          }
+        }
+
+
+        
+        /// <summary>
+        /// Gets or sets the <i>filter manger</i> 
+        /// </summary>
+        public DgvFilterManager FilterManager {
+            set { mFilterManager = value; }
+            get { return mFilterManager; }
+        }
+                    
+
+        
+        /// <summary>
+        /// Gets or sets the currently visibile <i>column filter</i> control
+        /// </summary> 
+        public DgvBaseColumnFilter CurrentColumnFilter {
+            get { return mCurrentColumnFilter; }
+            set {
+                  // Called once: store the original size difference of the filterhost and the filterClientArea
+                  if (mSizeDifference == Size.Empty) { 
+                      mSizeDifference = System.Drawing.Size.Subtract(this.Size, FilterClientArea.Size);
+                      this.MinimumSize = this.Size;
+                  }
+                  if (mCurrentColumnFilter != null) mCurrentColumnFilter.Visible = false;
+                  mCurrentColumnFilter = value;
+                  DoAutoFit();
+                  if (CurrentColumnFilterChanged != null) {
+                      EventArgs e = new EventArgs();
+                      CurrentColumnFilterChanged(this, e);
+                  }
+                  mCurrentColumnFilter.Visible = true;
+            }
+        }
+
+
+        /// <summary>
+        /// Gets the original size difference of the <i>filter host</i> and the <see cref="DgvBaseFilterHost.FilterClientArea"/>.
+        /// </summary>
+        public Size SizeDifference {
+            get { return mSizeDifference; }
+        }
+
+        #endregion
+
+
+        #region HELPERS
+
+        /// <summary>
+        /// Performs growing / shrinking of the <i>filter host</i> to best fit the current visibile <i>column filter</i>.
+        /// </summary>
+        /// <remarks>
+        /// Ovverride this method to provide your own resize logic.
+        /// </remarks>
+        protected virtual void DoAutoFit() {
+            Size NewHostSize = Size.Add(mSizeDifference, mCurrentColumnFilter.Size);
+            NewHostSize.Width = Math.Max(NewHostSize.Width, this.MinimumSize.Width);
+            NewHostSize.Height= Math.Max(NewHostSize.Height, this.MinimumSize.Height);
+            this.Size = NewHostSize;
+
+            FilterClientArea.Size = Size.Subtract(NewHostSize, mSizeDifference);
+            AlignFilter();
+        }
+
+        /// <summary>
+        /// Aligns the <i>column filter</i> into the filter client area.
+        /// </summary>
+        /// <remarks>
+        /// Ovverride this method to provide your own alignment logic.
+        /// </remarks>
+        protected void AlignFilter() { 
+            int x = 0; // VFilterAlignmentType.Left:
+            int y = 0; // HFilterAlignmentType.Top:
+            switch (mCurrentColumnFilter.VFilterAlignment){
+                case VFilterAlignment.Right:
+                    x = FilterClientArea.Width - mCurrentColumnFilter.Width;
+                 break;
+                case VFilterAlignment.Center:
+                    x = (FilterClientArea.Width - mCurrentColumnFilter.Width) / 2;
+                 break;
+            }
+
+            switch (mCurrentColumnFilter.HFilterAlignment) {
+                case HFilterAlignment.Bottom:
+                    y = FilterClientArea.Height - mCurrentColumnFilter.Height;
+                    break;
+                case HFilterAlignment.Middle:
+                    y = (FilterClientArea.Height - mCurrentColumnFilter.Height) / 2;
+                    break;
+            }
+            mCurrentColumnFilter.Location = new Point(x, y);
+        }
+
+        /// <summary>
+        /// Returns a region based on the transparency color of a bitmap.
+        /// </summary>
+        /// <param name="bitmap">The bitmap.</param>
+        /// <param name="transparencyColor">The transparency color.</param>
+        /// <returns>A region</returns>
+        public static Region BitmapToRegion(Bitmap bitmap, Color transparencyColor) {
+            if (bitmap == null)
+                throw new ArgumentNullException("Bitmap", "Bitmap cannot be null!");
+
+            int height = bitmap.Height;
+            int width = bitmap.Width;
+
+            GraphicsPath path = new GraphicsPath();
+
+            for (int j = 0; j < height; j++)
+                for (int i = 0; i < width; i++) {
+                    if (bitmap.GetPixel(i, j) == transparencyColor)
+                        continue;
+
+                    int x0 = i;
+
+                    while ((i < width) && (bitmap.GetPixel(i, j) != transparencyColor))
+                        i++;
+
+                    path.AddRectangle(new Rectangle(x0, j, i - x0, 1));
+                }
+
+            Region region = new Region(path);
+            path.Dispose();
+            return region;
+        }
+
+        /// <summary>
+        /// Registers the a combo box.
+        /// </summary>
+        /// <param name="comboBox">The combo box.</param>
+        /// <remarks>
+        /// When the user clicks on an <b>ComboBox</b> item that is outside of the
+        /// host area, this cause an unwanted closing of the <i>filter host</i>. 
+        /// If you use a <b>ComboBox</b> in a customized <i>column filter</i>, 
+        /// be sure to call this method in your filter intitialitazion code.
+        /// </remarks>
+        public void RegisterComboBox (ComboBox comboBox){
+            comboBox.DropDown += new EventHandler(onDropDown);
+            comboBox.DropDownClosed += new EventHandler(onDropDownClosed);
+        }
+
+        private void onDropDown(object sender, EventArgs e)
+        {
+            this.Popup.AutoClose = false;
+        }
+
+        private void onDropDownClosed(object sender, EventArgs e)
+        {
+            this.Popup.AutoClose = true;
+        }
+
+        #endregion
+
+
+    }
+}

File FilterPopup/DgvFilterManager.cs

View file
  • Ignore whitespace
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Windows.Forms;
+using System.Drawing;
+using System.Data;
+using System.ComponentModel;
+
+namespace DgvFilterPopup {
+
+     /// <summary>
+     /// The main class involved in adding filtering capabilities to a DataGridView.  
+     /// </summary>
+     /// <remarks>
+     /// This is the class that you use to add filtering capabilities to a <b>DataGridView</b>. The
+     /// <b>DataGridView</b> must be data bound to a <b>DataTable</b>, a <b>DataView</b> or a <b>BindingSource</b> which in turn is
+     /// bound to one of these two.
+     /// When you assign a <b>DataGridView</b> to a <b>DgvFilterManager</b>, it attaches some handlers to respond 
+     /// to right click on column headers and to perform some custom painting on the grid. 
+     /// When the user right clicks a column header, the <b>DgvFilterManager</b> shows a popup near the column.
+     /// This popup is a control that serves as host for other controls, one for each column. Only one of
+     /// these child controls is visibile, based on clicked column. 
+     /// We have one <i>filter host</i> control and many <i>column filter</i> child controls. 
+     /// <para>
+     /// The <i>filter host</i> control must be a derivation of the <see cref="DgvBaseFilterHost"/> class, while filter controls must be
+     /// derived by the <see cref="DgvBaseColumnFilter"/> class. These two classes don't provide any user interface. 
+     /// As a default, <b>DgvFilterManager</b> uses the standard derivation <b>DgvFilterHost</b> and, depending on column type and data type,
+     /// one of the standard derivations: <see cref="DgvTextBoxColumnFilter"/>
+     /// , <see cref="DgvCheckBoxColumnFilter"/>, <see cref="DgvComboBoxColumnFilter"/> 
+     /// and <see cref="DgvDateColumnFilter"/>. 
+     /// </para>
+     /// <para>
+     /// When a <b>DataGridView</b> is attached, the manager perform the following actions: 
+     /// <ul>
+     /// <li>it creates a <i>filter host</i>, that is an instance of the <b>DgvFilterHost</b> class. If you previously provided a
+     /// <i>filter host</i>, this step is skipped.</li> 
+     /// <li>it creates an array of <b>DgvBaseColumnFilter</b>, one per column, and initializes each element to a specialization 
+     /// of <b>DgvBaseColumnFilter</b>. If <see cref="DgvFilterManager.AutoCreateFilters"/> is false, this step is skipped.
+     /// </li>
+     /// </ul>
+     /// </para>
+     /// <para>
+     /// You can force a specific <i>column filter</i> for a certain column, intervening in this process through the events 
+     /// <see cref="DgvFilterManager.ColumnFilterAdding"/> and <see cref="DgvFilterManager.ColumnFilterAdded"/>. You can also intervene, after the entire process, replacing 
+     /// a <i>column filter</i> instance in the array with another instance you created. 
+     /// </para>
+     /// </remarks>
+
+    public class DgvFilterManager {
+
+        #region PRIVATE FIELDS
+
+        private DgvBaseFilterHost mFilterHost;      // The host UserControl to popup
+        private DataGridView mDataGridView;         // The DataGridView to which apply filtering
+        private DataView mBoundDataView;            // The DataView to which the DataGridView is bound
+        BindingSource mBindingSource;               // The BindingSource, if any, to which the DataGridView is bound
+
+
+        private string mBaseFilter = "";            // Developer provided filter expression
+        private int mCurrentColumnIndex = -1;       // Column Index of currently visibile filter
+
+        private List<DgvBaseColumnFilter> mColumnFilterList;    // List of ColumnFilter objects
+        private bool mAutoCreateFilters = true;
+        private bool mFilterIsActive = false;
+
+        #endregion
+        
+        
+        #region EVENTS
+
+
+        /// <summary>
+        /// Occurs when a <i>column filter</i> instance for a column is about to be automatically created.
+        /// </summary>
+        /// <remarks>
+        /// Using this event you can set the <see cref="ColumnFilterEventArgs.ColumnFilter"/> 
+        /// property to force the <see cref="DgvBaseColumnFilter"/> specialization to use for the 
+        /// column. 
+        /// This event is raised only if <see cref="DgvFilterManager.AutoCreateFilters"/> is true.
+        /// </remarks>
+        public event ColumnFilterEventHandler ColumnFilterAdding;
+
+
+        /// <summary>
+        /// Occurs when a <i>column filter</i> instance is created.
+        /// This event is raised only if <see cref="DgvFilterManager.AutoCreateFilters"/> is true.
+        /// </summary>
+        public event ColumnFilterEventHandler ColumnFilterAdded;
+
+
+        /// <summary>
+        /// Occurs when the popup is about to be shown
+        /// </summary>
+        /// <remarks>
+        /// Use this event to customize the popup position. Set the Handled property of the event argument to <c>true</c>.
+        /// </remarks>
+        public event ColumnFilterEventHandler PopupShowing;
+
+
+        #endregion
+
+        
+        #region CONSTRUCTORS
+
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DgvFilterManager"/> class.
+        /// </summary>
+        public DgvFilterManager() { }
+
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DgvFilterManager"/> class.
+        /// </summary>
+        /// <param name="dataGridView">The <b>DataGridView</b> to which attach filtering capabilities</param>
+        /// <param name="autoCreateFilters">if set to <c>true</c> automatically creates a <i>column filter</i> for each column</param>
+        public DgvFilterManager(DataGridView dataGridView, bool autoCreateFilters) { 
+            this.mAutoCreateFilters = autoCreateFilters;
+            this.DataGridView = dataGridView;
+        }
+
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DgvFilterManager"/> class.
+        /// </summary>
+        /// <param name="dataGridView">The <b>DataGridView</b> to which attach filtering capabilities.</param>
+        public DgvFilterManager(DataGridView dataGridView) : this(dataGridView, true) { }
+
+        #endregion
+        
+
+        #region PROPERTIES
+
+        /// <summary>
+        /// Gets or sets a value indicating whether the manager must create <i>column filters</i>.
+        /// </summary>
+        /// <value><c>true</c> by default.</value>
+        public bool AutoCreateFilters {
+            get { return mAutoCreateFilters; }
+            set { mAutoCreateFilters = value; }
+        }
+
+
+
+        /// <summary>
+        /// Gets and sets the <i>filter host</i> to use. 
+        /// </summary>
+        /// <remarks>
+        /// The default <i>filter host</i> is an instance of <see cref="DgvFilterHost"/>
+        /// </remarks>
+        
+        public DgvBaseFilterHost FilterHost {
+            get {
+                if (mFilterHost == null) { 
+                    // If not provided, use the default FilterHost
+                    FilterHost = new DgvFilterHost();
+                } 
+                return mFilterHost;
+            }
+            set {
+                mFilterHost = value;
+                // initialize FilterManager to this object
+                mFilterHost.FilterManager = this;
+                mFilterHost.Popup.Closed += new ToolStripDropDownClosedEventHandler(Popup_Closed);
+
+            }
+        }
+
+
+
+        /// <summary>
+        /// Gets and sets the DataGridView to which apply filtering capabilities.
+        /// </summary>
+        /// <remarks>
+        /// <para>
+        /// When a <b>DataGridView</b> is attached, the manager perform the following actions: 
+        /// <ul>
+        /// <li>it creates a <i>filter host</i>, that is an instance of the <b>DgvFilterHost</b> class. If you previously provided a
+        /// <i>filter host</i>, this step is skipped.</li> 
+        /// <li>it creates an array of <b>DgvBaseColumnFilter</b>, one per column, and initializes each element to a specialization 
+        /// of <b>DgvBaseColumnFilter</b>. If <see cref="DgvFilterManager.AutoCreateFilters"/> is false, this step is skipped.
+        /// </li>
+        /// </ul>
+        /// </para>
+        /// <para>
+        /// You can force a specific <i>column filter</i> for a certain column, intervening in this process through the events 
+        /// <see cref="DgvFilterManager.ColumnFilterAdding"/> and <see cref="DgvFilterManager.ColumnFilterAdded"/>. You can also intervene, after the entire process, replacing 
+        /// a <i>column filter</i> instance in the array with another instance you created. 
+        /// </para>
+        /// </remarks>
+        public DataGridView DataGridView {
+            get {
+                return mDataGridView;
+            }
+            set {
+                mDataGridView = value;
+                mColumnFilterList = new List<DgvBaseColumnFilter>(mDataGridView.Columns.Count);
+                FindDataView();
+                mDataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+                mDataGridView.CellMouseClick += new DataGridViewCellMouseEventHandler(mDataGridView_CellMouseClick);
+                mDataGridView.CellPainting += new DataGridViewCellPaintingEventHandler(mDataGridView_CellPainting);
+                mDataGridView.ColumnAdded +=new DataGridViewColumnEventHandler(mDataGridView_ColumnAdded);
+                mDataGridView.ColumnRemoved += new DataGridViewColumnEventHandler(mDataGridView_ColumnRemoved);
+                if (mDataGridView == null) return;
+                foreach (DataGridViewColumn c in mDataGridView.Columns) {
+                    mColumnFilterList.Add(null);
+                    CreateColumnFilter(c);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets and sets developer provided filter expression. This expression
+        /// will be "merged" with end-user created filters.
+        /// </summary>
+        /// <value>The base filter.</value>
+
+        public string BaseFilter {
+            get { return mBaseFilter; }
+            set { mBaseFilter = value; RebuildFilter(); }
+        }
+
+
+        /// <summary>
+        /// Gets or sets the <i>column filter</i> control related to the ColumnIndex
+        /// </summary>
+        /// <param name="ColumnIndex">The index of the <b>DataGridView</b> column</param>
+        /// <returns>the <b>DgvBaseColumnFilter</b> related to the <b>DataGridView</b> column</returns>
+        /// <remarks>
+        /// This indexer allow you to get and set the <i>column filter</i> instance for the column. 
+        /// You can set one of the standard <i>column filter</i> implementation or an instance 
+        /// of your own <b>DgvBaseFilterColumn</b> specialization.
+        /// </remarks>
+        public DgvBaseColumnFilter this[int ColumnIndex] {
+            get { return mColumnFilterList[ColumnIndex]; }
+            set { mColumnFilterList[ColumnIndex] = value; 
+                  value.Init(this, FilterHost, mDataGridView.Columns[ColumnIndex], mBoundDataView);
+            }
+        }
+        
+
+        /// <summary>
+        /// Gets or sets the <i>column filter</i> control related to the ColumnName
+        /// </summary>
+        /// <param name="ColumnName">The name of the <b>DataGridView</b> column</param>
+        /// <returns>the DgvBaseColumnFilter related to the <b>DataGridView</b> column</returns>
+        /// <remarks>
+        /// This indexer allow you to get and set the <i>column filter</i> instance for the column. 
+        /// You can set one of the standard <i>column filter</i> implementation or an instance 
+        /// of your own <b>DgvBaseFilterColumn</b> specialization.
+        /// </remarks>
+        public DgvBaseColumnFilter this[string ColumnName] {
+            get { return mColumnFilterList[mDataGridView.Columns[ColumnName].Index]; }
+            set { 
+                this[mDataGridView.Columns[ColumnName].Index] = value;
+            }
+        }
+
+
+
+        #endregion
+
+        
+        #region DATAGRIDVIEW EVENT HANDLERS
+
+        private void mDataGridView_ColumnRemoved(object sender, DataGridViewColumnEventArgs e) {
+            mColumnFilterList.RemoveAt(e.Column.Index);
+        }
+
+        private void mDataGridView_ColumnAdded(object sender, DataGridViewColumnEventArgs e) {
+            FindDataView();
+            mColumnFilterList.Insert(e.Column.Index, null);
+            CreateColumnFilter(e.Column);
+        }
+
+
+        /// <summary>
+        /// Shows the popup when user right-clicks a column header
+        /// </summary>
+        /// <param name="sender">The event source.</param>
+        /// <param name="e">The <see cref="System.Windows.Forms.DataGridViewCellMouseEventArgs"/> instance containing the event data.</param>
+        protected virtual void mDataGridView_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e) {
+            if (e.Button == MouseButtons.Right && e.RowIndex == -1 && e.ColumnIndex > -1) {
+                ShowPopup(e.ColumnIndex);
+            }
+        }
+
+        //Based on filters state, call the appropriate protected paint helpers
+        private void mDataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e) {
+            if (e.RowIndex != -1) return; //skip if it is not the header row
+
+            //Cell Origin
+            if (e.RowIndex == -1 && e.ColumnIndex == -1 && mFilterIsActive) {
+                OnFilteredGridPaint(sender, e);
+                return;
+            }
+
+            if (FilterHost.Popup.Visible) {
+                OnHighlightedColumnPaint(sender, e);
+            }
+
+            if (e.ColumnIndex == -1) return;
+            if (mColumnFilterList[e.ColumnIndex] != null && mColumnFilterList[e.ColumnIndex].Active) {
+                OnFilteredColumnPaint(sender, e);
+            }
+        }
+
+
+        /// <summary>
+        /// Paints a funnel icon in the cell origin when some column is filtered.
+        /// </summary>
+        /// <param name="sender">The sender</param>
+        /// <param name="e">The <see cref="System.Windows.Forms.DataGridViewCellPaintingEventArgs"/> instance containing the event data.</param>
+        /// <remarks>
+        /// Override this method to provide your own painting
+        /// </remarks>
+        protected virtual void OnFilteredGridPaint(object sender, DataGridViewCellPaintingEventArgs e) {
+            e.Graphics.FillRectangle(Brushes.White, e.CellBounds);
+            e.Paint(e.CellBounds, e.PaintParts & ~DataGridViewPaintParts.Background);
+            Rectangle r = new Rectangle(e.CellBounds.X + 1, e.CellBounds.Y + 1, e.CellBounds.Width - 3, e.CellBounds.Height - 4);
+            e.Graphics.DrawImage(FunnelPicture, (e.CellBounds.Width - FunnelPicture.Width) / 2, (e.CellBounds.Height - FunnelPicture.Height) / 2, FunnelPicture.Width, FunnelPicture.Height);
+            e.Graphics.DrawRectangle(Pens.Black, r);
+
+            e.Handled = true;
+
+            //e.Paint(e.CellBounds, DataGridViewPaintParts.All);
+            //e.Graphics.DrawImage(FunnelPicture, (e.CellBounds.Width - FunnelPicture.Width) / 2, (e.CellBounds.Height - FunnelPicture.Height) / 2, FunnelPicture.Width, FunnelPicture.Height);
+            //e.Handled = true;
+        }
+
+        /// <summary>
+        /// Performs customized column header painting when the popup is visibile. 
+        /// </summary>
+        /// <param name="sender">The sender.</param>
+        /// <param name="e">The <see cref="System.Windows.Forms.DataGridViewCellPaintingEventArgs"/> instance containing the event data.</param>
+        /// <remarks>
+        /// Override this method to provide your own painting
+        /// </remarks>
+        protected virtual void OnHighlightedColumnPaint(object sender, DataGridViewCellPaintingEventArgs e) {
+            if (e.ColumnIndex != mCurrentColumnIndex || e.RowIndex != -1) return;
+            e.Paint(e.CellBounds,DataGridViewPaintParts.All );
+            Rectangle r = new Rectangle(e.CellBounds.X + 1, e.CellBounds.Y + 1, e.CellBounds.Width - 3, e.CellBounds.Height - 4);
+            e.Graphics.DrawRectangle(Pens.Yellow, r);
+            e.Handled = true;
+        }
+
+        /// <summary>
+        /// Performs customized column header painting when the column is filtered.
+        /// </summary>
+        /// <param name="sender">The sender.</param>
+        /// <param name="e">The <see cref="System.Windows.Forms.DataGridViewCellPaintingEventArgs"/> instance containing the event data.</param>
+        /// <remarks>
+        /// Override this method to provide your own painting
+        /// </remarks>
+        protected virtual void OnFilteredColumnPaint(object sender, DataGridViewCellPaintingEventArgs e) {
+            e.Graphics.FillRectangle(Brushes.White, e.CellBounds);
+            e.Paint(e.CellBounds, e.PaintParts & ~DataGridViewPaintParts.Background);
+            Rectangle r = new Rectangle(e.CellBounds.X + 1, e.CellBounds.Y + 1, e.CellBounds.Width - 3, e.CellBounds.Height - 4);
+            e.Graphics.DrawRectangle(Pens.Black, r);
+            e.Handled = true;
+
+        }
+
+        #endregion
+
+
+        #region FILTERHOST MANAGING
+
+        //Forces column header repaint when popup is closed, cleaning customized painting performed by OnHighlightedColumnPaint
+        private void Popup_Closed(object sender, ToolStripDropDownClosedEventArgs e) {
+            mDataGridView.InvalidateCell(mCurrentColumnIndex, -1);   // Force header repaint (to hide the selection yellow frame)
+        }
+
+
+        /// <summary>
+        /// Shows the popup.
+        /// </summary>
+        /// <param name="ColumnIndex">Index of the column.</param>
+        public void ShowPopup(int ColumnIndex) {
+            if (mColumnFilterList[ColumnIndex] == null) return; // non-data column
+            int OldColumnIndex = mCurrentColumnIndex;
+            mCurrentColumnIndex = ColumnIndex;
+            Rectangle r = mDataGridView.GetCellDisplayRectangle(ColumnIndex, -1, false); // get the header size info
+            FilterHost.CurrentColumnFilter = mColumnFilterList[ColumnIndex];
+            try {
+                //use "try" because old column could have been removed
+                mDataGridView.InvalidateCell(OldColumnIndex, -1);
+            } catch { }
+            ColumnFilterEventArgs e = new ColumnFilterEventArgs(mDataGridView.Columns[ColumnIndex], mColumnFilterList[ColumnIndex]);
+            if (PopupShowing != null) PopupShowing(this, e);
+            if (!e.Handled) FilterHost.Popup.Show(mDataGridView, r.X + r.Width - 4, r.Y - 10); // show the filterhost popup near the column
+            FilterHost.Popup.Focus();
+            
+            mDataGridView.InvalidateCell(mCurrentColumnIndex, -1);  // Force header repaint (to show a selection yellow frame)
+
+        }
+
+        #endregion
+        
+
+        #region COLUMN FILTERS MANAGING
+
+
+        /// <summary>
+        /// Activates / Deactivates the filter for the column specified by ColumnIndex.
+        /// </summary>
+        /// <param name="Active">The active state to set</param>
+        /// <param name="ColumnIndex">Index of the column.</param>
+        public void ActivateFilter(bool Active, int ColumnIndex) {
+            this[ColumnIndex].Active = Active;
+            RebuildFilter();
+        }
+
+
+
+        /// <summary>
+        /// Activates / Deactivates the filter for the column specified by ColumnName.
+        /// </summary>
+        /// <param name="Active">The active state to set</param>
+        /// <param name="ColumnName">Name of the column.</param>
+        public void ActivateFilter(bool Active, string ColumnName) {
+            this[ColumnName].Active = Active;
+            RebuildFilter();
+        }
+
+
+        /// <summary>
+        /// Activates / Deactivates the filter for the current, that is last right-clicked, column.
+        /// </summary>
+        /// <param name="Active">The active state to set</param>
+        public void ActivateFilter(bool Active) {
+            if (mCurrentColumnIndex == -1) return;
+            this[mCurrentColumnIndex].Active = Active;
+            if (Active) this[mCurrentColumnIndex].FilterExpressionBuild();
+            RebuildFilter();
+        }
+
+
+
+        /// <summary>
+        /// Activates / Deactivates all filters.
+        /// </summary>
+        /// <param name="Active">The active state to set</param>
+        public void ActivateAllFilters(bool Active) {
+            foreach (DgvBaseColumnFilter CF in mColumnFilterList) {
+                if (CF == null) continue;
+                CF.Active = Active;
+                if (Active) CF.FilterExpressionBuild();
+            }
+            RebuildFilter();
+        }
+
+
+
+        /// <summary>
+        /// Rebuilds the whole filter expression.
+        /// </summary>
+        /// <remarks>
+        /// The whole filter expression is the conjunction of each <i>column filter</i> and the <see cref="BaseFilter"/>. 
+        /// Call this method to refresh and apply the whole filter expression.
+        /// </remarks>
+        public void RebuildFilter() {
+            mFilterIsActive = false;
+            string Filter = "";
+            foreach (DgvBaseColumnFilter CF in mColumnFilterList) {
+                if (CF == null) continue;
+                if (CF.Active && CF.FilterExpression != "") {
+                    Filter += " AND (" + CF.FilterExpression + ")";
+                    CF.DataGridViewColumn.HeaderText = CF.FilterCaption;
+                }
+                else {
+                    CF.DataGridViewColumn.HeaderText = CF.OriginalDataGridViewColumnHeaderText;
+                }
+
+            }
+            if (Filter != "") {
+                mFilterIsActive = true;
+                Filter = (mBaseFilter == "") ? "1=1 " + Filter : mBaseFilter + " " + Filter;
+            }
+            else
+                Filter = mBaseFilter;
+
+            // Apply the filter only if any changes occurred
+            try {
+                if (mBindingSource != null) {
+                    if (mBindingSource.Filter != Filter) mBindingSource.Filter = Filter;
+                } else 
+                {
+                    if (mBoundDataView.RowFilter != Filter)mBoundDataView.RowFilter = Filter;
+                }
+            } catch { Console.WriteLine ("Invalid filter: " + Filter);}
+
+        }
+
+
+        #endregion
+
+        
+        #region HELPERS
+
+        // Checks if the DataGridView is data bound and the data source finally resolves to a DataView.
+        private void FindDataView() {
+            mBindingSource = null;
+            object DataSource = mDataGridView.DataSource;
+            string DataMember = mDataGridView.DataMember;
+
+            string ExceptionMsg = "DataGridViewFilter can only work with bound DataGridView. The DataSource must be a DataSet, a DataTable, a DataView or a BindingSource which is bound to a DataSet, a DataTable or a DataView ";
+
+            while (!(DataSource is DataView)){
+
+                if (DataSource == null) {
+                    return;
+                }
+
+                if (DataSource is BindingSource) {
+                    mBindingSource = (BindingSource)DataSource;
+                    DataMember = ((BindingSource)DataSource).DataMember;
+                    DataSource = ((BindingSource)DataSource).DataSource;
+                    continue;
+                }
+                if (DataSource is DataSet) { 
+                    DataSource = ((DataSet)DataSource).Tables[DataMember];
+                    DataMember = "";
+                    continue;
+                }
+                if (DataSource is DataTable){
+                    DataSource = ((DataTable)DataSource).DefaultView;
+                    break;
+                }
+                //other types are not allowed
+                throw new Exception(ExceptionMsg);
+            }
+            mBoundDataView = (DataView)DataSource;
+        }
+
+
+        //The funnel picture
+        private static Image mFilterPicture;
+
+
+        /// <summary>
+        /// Gets a funnel picture.
+        /// </summary>
+        public static Image FunnelPicture {
+            get { 
+                if (mFilterPicture==null) {
+                    System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DgvFilterHost));
+                    mFilterPicture = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
+                }
+                return mFilterPicture;
+            }
+        }
+
+        
+        private void CreateColumnFilter(DataGridViewColumn c) {
+            if (!mAutoCreateFilters) return;
+            //Raise the event about column filter creation
+            ColumnFilterEventArgs e = new ColumnFilterEventArgs(c,null);
+            if (ColumnFilterAdding != null) ColumnFilterAdding(this, e);
+            //if not provided, by an event handler, proceed with standard filter creation
+            if (e.ColumnFilter==null) {
+                Type DataType = null;
+                if (c.DataPropertyName != "") {
+                    DataType = mBoundDataView.Table.Columns[c.DataPropertyName].DataType;
+
+                    switch (c.GetType().Name) {
+                        case "DataGridViewComboBoxColumn":
+                            e.ColumnFilter = new DgvComboBoxColumnFilter();
+                            break;
+                        case "DataGridViewCheckBoxColumn":
+                            e.ColumnFilter = new DgvCheckBoxColumnFilter();
+                            break;
+                        case "DataGridViewTextBoxColumn":
+                            if (DataType == typeof(DateTime)) {
+                                e.ColumnFilter = new DgvDateColumnFilter();
+                            }
+                            else
+                                e.ColumnFilter = new DgvTextBoxColumnFilter();
+                            break;
+                    }
+                }
+            }
+            mColumnFilterList[c.Index] = e.ColumnFilter;
+            if (e.ColumnFilter != null) { // == null when non-data column
+                if (ColumnFilterAdded != null) ColumnFilterAdded(this, e);
+                e.ColumnFilter.Init(this, FilterHost, c, mBoundDataView);
+            }        
+        }
+
+        #endregion
+
+
+
+    }
+}

File FilterPopup/Extensions/DgvDateRangeColumnFilter.Designer.cs

View file
  • Ignore whitespace
+namespace DgvFilterPopup {
+    partial class DgvDateRangeColumnFilter {
+        /// <summary> 
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary> 
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing) {
+            if (disposing && (components != null)) {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Component Designer generated code
+
+        /// <summary> 
+        /// Required method for Designer support - do not modify 
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent() {
+            this.comboBoxOperator = new System.Windows.Forms.ComboBox();
+            this.dateTimePickerValue = new System.Windows.Forms.DateTimePicker();
+            this.dateTimePickerValue2 = new System.Windows.Forms.DateTimePicker();
+            this.SuspendLayout();
+            // 
+            // comboBoxOperator
+            // 
+            this.comboBoxOperator.FormattingEnabled = true;
+            this.comboBoxOperator.Location = new System.Drawing.Point(3, 3);
+            this.comboBoxOperator.Name = "comboBoxOperator";
+            this.comboBoxOperator.Size = new System.Drawing.Size(49, 21);
+            this.comboBoxOperator.TabIndex = 0;
+            // 
+            // dateTimePickerValue
+            // 
+            this.dateTimePickerValue.Format = System.Windows.Forms.DateTimePickerFormat.Short;
+            this.dateTimePickerValue.Location = new System.Drawing.Point(58, 3);
+            this.dateTimePickerValue.Name = "dateTimePickerValue";
+            this.dateTimePickerValue.Size = new System.Drawing.Size(127, 20);
+            this.dateTimePickerValue.TabIndex = 1;
+            // 
+            // dateTimePickerValueUntil
+            // 
+            this.dateTimePickerValue2.Format = System.Windows.Forms.DateTimePickerFormat.Short;
+            this.dateTimePickerValue2.Location = new System.Drawing.Point(58, 29);
+            this.dateTimePickerValue2.Name = "dateTimePickerValueUntil";
+            this.dateTimePickerValue2.Size = new System.Drawing.Size(127, 20);
+            this.dateTimePickerValue2.TabIndex = 2;
+            // 
+            // DgvDateRangeColumnFilter
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.BackColor = System.Drawing.Color.Transparent;
+            this.Controls.Add(this.dateTimePickerValue2);
+            this.Controls.Add(this.dateTimePickerValue);
+            this.Controls.Add(this.comboBoxOperator);
+            this.Name = "DgvDateRangeColumnFilter";
+            this.Size = new System.Drawing.Size(191, 54);
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.ComboBox comboBoxOperator;
+        private System.Windows.Forms.DateTimePicker dateTimePickerValue;
+        private System.Windows.Forms.DateTimePicker dateTimePickerValue2;
+    }
+}

File FilterPopup/Extensions/DgvDateRangeColumnFilter.cs

View file
  • Ignore whitespace
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+
+namespace DgvFilterPopup {
+
+    /// <summary>
+    /// An extended <i>column filter</i> implementation allowing filters on date ranges.
+    /// </summary>
+    public partial class DgvDateRangeColumnFilter : DgvBaseColumnFilter {
+
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="DgvDateRangeColumnFilter"/> class.
+        /// </summary>
+        public DgvDateRangeColumnFilter() {
+            InitializeComponent();
+            comboBoxOperator.SelectedValueChanged += new EventHandler(onFilterChanged);
+            dateTimePickerValue.TextChanged += new EventHandler(onFilterChanged);
+            dateTimePickerValue2.TextChanged += new EventHandler(onFilterChanged);
+        }
+
+        /// <summary>
+        /// Gets the ComboBox control containing the available operators.
+        /// </summary>
+        public ComboBox ComboBoxOperator { get { return comboBoxOperator; }}
+
+        
+        /// <summary>
+        /// Gets the DateTimePicker control containing the date value.
+        /// </summary>
+        public DateTimePicker DateTimePickerValue { get { return dateTimePickerValue; }}
+
+        /// <summary>
+        /// Gets the DateTimePicker control containing the second date value.
+        /// </summary>
+        public DateTimePicker DateTimePickerValue2 { get { return dateTimePickerValue2; }}
+
+        /// <summary>
+        /// Perform filter initialitazion and raises the FilterInitializing event.
+        /// </summary>
+        /// <param name="sender">The source of the event.</param>
+        /// <param name="e">The <see cref="System.ComponentModel.CancelEventArgs"/> instance containing the event data.</param>
+        /// <remarks>
+        /// When this <i>column filter</i> control is added to the <i>column filters</i> array of the <i>filter manager</i>,
+        /// the latter calls the <see cref="DgvBaseColumnFilter.Init"/> method which, in turn, calls this method.
+        /// You can ovverride this method to provide initialization code or you can create an event handler and 
+        /// set the <i>Cancel</i> property of event argument to true, to skip standard initialization.
+        /// </remarks>
+        protected override void OnFilterInitializing(object sender, CancelEventArgs e) {
+            base.OnFilterInitializing(sender, e);
+            if (e.Cancel) return;
+            comboBoxOperator.Items.AddRange (new object[] { "[...]","=", "<>", ">", "<", "<=", ">=", "= Ř", "<> Ř" });
+            comboBoxOperator.SelectedIndex = 0;
+            this.FilterHost.RegisterComboBox(comboBoxOperator);
+        }
+
+        /// <summary>
+        /// Builds the filter expression and raises the FilterExpressionBuilding event
+        /// </summary>
+        /// <param name="sender">The event source.</param>
+        /// <param name="e">The <see cref="System.ComponentModel.CancelEventArgs"/> instance containing the event data.</param>
+        /// <remarks>
+        /// Override <b>OnFilterExpressionBuilding</b> to provide a filter expression construction
+        /// logic and to set the values of the <see cref="DgvBaseColumnFilter.FilterExpression"/> and <see cref="DgvBaseColumnFilter.FilterCaption"/> properties.
+        /// The <see cref="DgvFilterManager"/> will use these properties in constructing the whole filter expression and to change the header text of the filtered column.
+        /// Otherwise, you can create an event handler and set the <i>Cancel</i> property of event argument to true, to skip standard filter expression building logic.
+        /// </remarks>
+        protected override void OnFilterExpressionBuilding(object sender, CancelEventArgs e){
+         	base.OnFilterExpressionBuilding(sender, e);