यह आलेख क्रमिक रूप से एक सार्वभौमिक फ़िल्टर लिखने के लिए आवश्यक सभी चरणों का वर्णन करेगा जो मानक
SharePoint सूचियों (
XsltListWebPart या
ListWebPart से उत्तराधिकारी) से चयन की अनुमति देता है।
विकास
VisualStudio 2010 पर आयोजित किया गया था, जो केवल
SharePoint 2010 के साथ काम कर सकता है, इसलिए नीचे वर्णित सब कुछ
SharePoint नींव 2010 प्लेटफ़ॉर्म पर परीक्षण किया गया था, हालांकि, सबसे अधिक संभावना है, सब कुछ
SharePoint 2007 (
WSS 3.0 ) के लिए सही होगा।
मैंने विकास के माहौल को स्थापित करने और तैनात करने की प्रक्रिया का वर्णन नहीं किया है - इंटरनेट पर इसे खोजना आसान है, लेकिन मुझे मानक सूचियों को कैसे फ़िल्टर करना है, इसका कोई अच्छा और स्पष्ट उदाहरण नहीं मिला।
तो, न्यूनतम कार्य: एक
वेबपार्ट बनाएं जो इस तरह
साझा की गई दस्तावेज़ सूची को फ़िल्टर कर सके:

यानी आप उपलब्ध सूची क्षेत्रों में से एक (न केवल दृश्यमान) का चयन कर सकते हैं, संभावित तुलना ऑपरेटरों में से एक निर्दिष्ट करें (समान, बराबर, अधिक, कम, आदि) और वास्तविक मूल्य। जब आप
Go बटन पर क्लिक करते हैं, तो सूची की सामग्री को हमारी स्थिति को पूरा करना चाहिए।
शुरुआत के लिए, हम सामान्य
SharePoint वेबपार्ट के एक-दूसरे के साथ बातचीत कर सकते हैं। दो या दो से अधिक
वेबपार्ट की बातचीत के लिए मानक विधि तथाकथित
प्रदाता -
उपभोक्ता तंत्र है।
शुरुआत में, एक इंटरफ़ेस परिभाषित किया गया है जिसके माध्यम से संचार किया जाएगा।
इंटरफ़ेस उदाहरणpublic interface ITextBoxString
{
string TextBoxString { get ; set ; }
}
उपभोक्ता तथाकथित प्रवेश बिंदु प्रकाशित करता है (वास्तव में, ये विधियां कुछ इंटरफ़ेस को एक पैरामीटर के रूप में लेती हैं और
कनेक्शनकोनसुम विशेषता के साथ चिह्नित हैं)।
उपभोक्ता उदाहरणpublic class StringConsumer : WebPart
{
private ITextBoxString _myProvider;
private Label _myLabel;
protected override void OnPreRender( EventArgs e)
{
EnsureChildControls();
if (_myProvider != null )
_myLabel.Text = _myProvider.TextBoxString;
}
protected override void CreateChildControls()
{
Controls.Clear();
_myLabel = new Label{Text = "Default text" };
Controls.Add(_myLabel);
}
[ConnectionConsumer( "String Consumer" , "StringConsumer" )]
public void TextBoxStringConsumer(ITextBoxString provider)
{
_myProvider = provider;
}
}
प्रदाता आउटगोइंग पॉइंट्स प्रकाशित करता है (तरीके जो इंटरफ़ेस को लौटाते हैं जो कि
कनेक्शनपॉइडर विशेषता के साथ चिह्नित हैं)।
प्रदाता उदाहरणpublic class StringProvider : WebPart, ITextBoxString
{
private TextBox _myTextBox;
[Personalizable]
public string TextBoxString { get { return _myTextBox.Text; } set { _myTextBox.Text = value ; } }
protected override void CreateChildControls()
{
Controls.Clear();
_myTextBox = new TextBox();
Controls.Add(_myTextBox);
Controls.Add( new Button {Text = "Change Text" });
}
[ConnectionProvider( "Provider for String From TextBox" , "TextBoxStringProvider" )]
public ITextBoxString TextBoxStringProvider()
{
return this ;
}
}
यदि
प्रदाता और
उपभोक्ता संचार बिंदुओं पर इंटरफेस मेल खाते हैं तो संचार स्थापित किया जा सकता है। इसके अलावा, पेज पर संबंधित वेबपार्ट्स रखने के बाद, उन्हें
कनेक्शन मेनू आइटम में
वेबपार्ट में से एक का चयन करके एक साथ जोड़ा जा सकता है। कनेक्शन स्थापित होने के बाद - प्रत्येक पृष्ठ रिफ्रेश (रेंडरिंग) के बाद, इंटरफ़ेस प्राप्त करने के लिए
प्रदाता विधि (
TextBoxStringProvider ) को सबसे पहले बुलाया जाएगा और परिणाम
उपभोक्ता विधि (
TextBoxStringConsumer ) को पास कर दिया जाएगा। सिद्धांत रूप में, सब कुछ सरल है। यह अकादमिक उदाहरण MSDN पर भी वर्णित है।
हालाँकि, हमें अपने स्वयं के प्रदाता को पूर्वनिर्धारित
उपभोक्ता , अर्थात्
वेबपार्ट , को
XsltListWebPart या
ListWebPart से वारिसों को
लिखना होगा । ऐसा करने के लिए, हमें यह जानने की जरूरत है कि वे किस संचार इंटरफेस का समर्थन करते हैं और उनके साथ कैसे काम करते हैं। अजीब लग सकता है क्योंकि यह जानकारी इंटरनेट पर बेहद दुर्लभ है। सिद्धांत रूप में, इस समस्या को हल करने वाले कुछ समाधान हैं (मुझे दो वाणिज्यिक परियोजनाएं मिलीं (
KWizCom List Filter Plus और
Roxority FilterZen Filter ) और एक भी खुला स्रोत नहीं)।
सावधान विश्लेषण और रिवर्स इंजीनियरिंग ने दिखाया कि दो इंटरफेस हैं जिनसे आप कनेक्ट कर सकते हैं:
ITransformableFilterValues और
IWebPartParameters ।
पहले
ITransformableFilterValues इंटरफ़ेस का उपयोग करते हुए,
आप सूची के केवल एक क्षेत्र का चयन
कर सकते हैं (शायद कई, लेकिन मुझे यह एक बार में नहीं मिला), हमारे प्रदाता और सूची के बीच संबंध स्थापित करते समय चयनित, और केवल फ़िल्टर किए गए मान के साथ फ़ील्ड मान के पूर्ण पत्राचार द्वारा (यानी ई। केवल ऑपरेशन "बराबर" लागू करना संभव है। इस प्रकार, यह मार्ग हमें शोभा नहीं देता।
IWebPartParameters का दूसरा इंटरफ़ेस दिलचस्प है, सबसे पहले, यह सभी सूची क्षेत्रों की सूची प्राप्त करना आसान बनाता है:
IWebPartParameterspublic void SetConsumerSchema(PropertyDescriptorCollection schema)
{
Owner.Parameters = schema;
}
और दूसरी बात, यह संकेत नहीं है कि किन क्षेत्रों को फ़िल्टर किया गया है।
GetParametersData विधि में, युग्म फ़ील्ड नाम के साथ एक शब्दकोश पास किया जाता है - चयन के लिए मूल्य:
IWebPartParameterspublic void GetParametersData(ParametersCallback callback)
{
var objParameters = new StateBag();
if (Owner._searchBox != null && ! string .IsNullOrEmpty(Owner._searchBox.Text))
{
objParameters.Add(Owner._comboBox.SelectedItem.Value, Owner._searchBox.Text);
}
callback(objParameters);
}
इसके अलावा, इस तरह से सेट किया गया फ़िल्टर उपयोगकर्ता द्वारा मैन्युअल रूप से बनाए गए स्तंभों के लिए फ़िल्टर के समान है (कॉलम को एक फ़िल्टर आइकन के साथ भी हाइलाइट किया जाएगा जो दर्शाता है कि फर्श का चयन किया गया है)। लेकिन, अफसोस, यह तरीका भी हमें शोभा नहीं देता, क्योंकि आपको केवल चयन मापदंडों की सख्त समानता से डेटा का चयन करने की अनुमति देता है।
क्या करें? यह पता चला है
कि आप किसी अन्य
वेबपार्ट को दूसरे तरीके से प्रभावित कर सकते हैं - बस इस
वेबपार्ट के मापदंडों को सही समय पर (चयन करने से पहले) बदल रहे हैं।
समय में एक उपयुक्त बिंदु
ओनलोड घटना होगी - जो पेज लोड होने के बाद उठाई जाती है, लेकिन इससे पहले कि डेटा प्राप्त हो। चर पैरामीटर सूची का Xml विवरण होगा, जो
XlstListWebPart के लिए
XmlDefinition गुण और
ListWebPart के लिए
ListViewXml में
संग्रहीत है । अन्य बातों के अलावा, इस Xml विवरण में एक CAML अनुरोध है, जिसमें डेटा चुनने के लिए आप हमारे लिए आवश्यक शर्तें सम्मिलित कर सकते हैं:
कोड नमूनाprivate string CreateQuery()
{
if (_searchBox != null && ! string .IsNullOrEmpty(_searchBox.Text))
return String .Format( "<{1}><FieldRef Name='{0}'/><Value Type='Text'>{2}</Value></{1}>" ,
_comboBox.SelectedItem.Value, _searchType.SelectedItem.Value, _searchBox.Text);
else
return "" ;
}
protected override void OnLoad( EventArgs e)
{
base .OnLoad(e);
var query = CreateQuery();
if (query == "" ) return ;
var part = WebPartManager.WebParts[0] as XsltListViewWebPart;
if (part == null ) return ;
var doc = new XmlDocument ();
doc.LoadXml(part.XmlDefinition);
var queryNode = doc.SelectSingleNode( "//Query" );
if (queryNode == null ) return ;
var whereNode = queryNode.SelectSingleNode( "Where" );
if (whereNode != null ) queryNode.RemoveChild(whereNode);
var newNode = doc.CreateNode( XmlNodeType .Element, "Where" , String .Empty);
newNode.InnerXml = query;
queryNode.AppendChild(newNode);
part.XmlDefinition = doc.OuterXml;
}
यहाँ, सिद्धांत रूप में, कुछ ऐसा है जिससे आप आगे के विकास के लिए निर्माण कर सकते हैं। मैंने एक ज्ञापन के रूप में खुद के लिए एक लेख लिखा, ताकि भूल न जाए। मुझे उम्मीद है कि कोई इसे उपयोगी भी पाएगा।