前兩天做一個項目的時候,由于頁面沒有限制textbox的輸入長度,所以,后臺直接報錯了,超出數據庫最大的長度。
數據庫的長度是按照字節來計算的,而且不同的編碼格式,漢字占用的字節長度又不相同,比如,我們用的是utf8,一個漢字是3個字節,而默認的default,一個漢字是2個字節。
textbox有個maxlength屬性,但是這個屬性是不太合乎要求的,因為這個長度,是限制了輸入的長度,比如設置20,則無論是數字、字母、漢字最大的長度都是20個,但是,對于數據庫來說,長度卻不相同了,所以,不能使用這個屬性。
為了,統一解決下這個問題,所以給textbox寫了附加屬性。
一、想要的效果
用了附加屬性,想達到一個什么效果呢,就是像設置maxlength一樣,一旦到了數據庫的字節長度,就不再能輸入了。
因此,最開始想找一個限制輸入的屬性,可惜我學的太淺薄,沒有找到相關的屬性,因此,最后在同事的提醒下,可以記錄上一次的內容,然后,如果超長,就用上一次的內容進行賦值
二、附加屬性
既然要用附加屬性,并且方便使用,那肯定要給開發者暴露出來至少兩個:maxbytelength用來設置最大的字節數,encodemodel用來設置編碼格式
encodemodel是用menu類型來做的,方便使用時直接敲內容
本來上面是直接想用encoding來做的,奈何它是抽象類,只好,寫個方法進行了一部轉化,并且把encoding類型的屬性進行private。
大致上也就是這么一個思路,下面上代碼,給需要的人使用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
public class maxbyteattachedproperty : dependencyobject { public enum encode { default , ascii, utf8, utf32, utf7, bigendianunicode, unicode } private static string getpretext(dependencyobject obj) { return ( string )obj.getvalue(pretextproperty); } private static void setpretext(dependencyobject obj, string value) { obj.setvalue(pretextproperty, value); } // using a dependencyproperty as the backing store for pretext. this enables animation, styling, binding, etc... private static readonly dependencyproperty pretextproperty = dependencyproperty.registerattached( "pretext" , typeof ( string ), typeof (maxbyteattachedproperty), new propertymetadata( "" )); public static int getmaxbytelength(dependencyobject obj) { return ( int )obj.getvalue(maxbytelengthproperty); } public static void setmaxbytelength(dependencyobject obj, int value) { obj.setvalue(maxbytelengthproperty, value); } // using a dependencyproperty as the backing store for maxbytelength. this enables animation, styling, binding, etc... public static readonly dependencyproperty maxbytelengthproperty = dependencyproperty.registerattached( "maxbytelength" , typeof ( int ), typeof (maxbyteattachedproperty), new propertymetadata(ontextboxpropertychanged)); private static void ontextboxpropertychanged(dependencyobject d, dependencypropertychangedeventargs e) { textbox tb = d as textbox; if (tb == null ) { return ; } tb.textchanged += tb_textchanged; } private static void tb_textchanged( object sender, textchangedeventargs e) { textbox tb = sender as textbox; if (isoutmaxbytelength(tb.text, tb)) { tb.text = getpretext(tb); tb.select(tb.text.length, 0); return ; } } public static encode getencodemodel(dependencyobject obj) { return (encode)obj.getvalue(encodemodelproperty); } public static void setencodemodel(dependencyobject obj, encode value) { obj.setvalue(encodemodelproperty, value); } // using a dependencyproperty as the backing store for encodem. this enables animation, styling, binding, etc... public static readonly dependencyproperty encodemodelproperty = dependencyproperty.registerattached( "encodemodel" , typeof (encode), typeof (maxbyteattachedproperty), new propertymetadata(encode.utf8, onencodemodelchanged)); private static void onencodemodelchanged(dependencyobject d, dependencypropertychangedeventargs e) { setem(d, getencodemodel(d)); } private static encoding getencodingmodel(dependencyobject obj) { return (encoding)obj.getvalue(encodingmodelproperty); } private static void setencodingmodel(dependencyobject obj, encoding value) { obj.setvalue(encodingmodelproperty, value); } // using a dependencyproperty as the backing store for encodingmodel. this enables animation, styling, binding, etc... private static readonly dependencyproperty encodingmodelproperty = dependencyproperty.registerattached( "encodingmodel" , typeof (encoding), typeof (maxbyteattachedproperty), new propertymetadata(encoding.utf8)); private static void setem(dependencyobject obj, encode e) { switch (e) { case encode. default : setencodingmodel(obj, encoding. default ); break ; case encode.ascii: setencodingmodel(obj, encoding.ascii); break ; case encode.utf8: setencodingmodel(obj, encoding.utf8); break ; case encode.utf32: setencodingmodel(obj, encoding.utf32); break ; case encode.utf7: setencodingmodel(obj, encoding.utf7); break ; case encode.bigendianunicode: setencodingmodel(obj, encoding.bigendianunicode); break ; case encode.unicode: setencodingmodel(obj, encoding.unicode); break ; default : break ; } } private static bool isoutmaxbytelength( string txt, dependencyobject obj) { int txtlength = getencodingmodel(obj).getbytes(txt).length; //文本長度 if (getmaxbytelength(obj) >= txtlength) { setpretext(obj, txt); return false ; } return true ; } } |
使用方法如下:
maxbytelength是必須設置的沒有進行默認,encodemodel可以不設置但是由于是我們自己用,所以默認是utf8,可以自行修改代碼,按照你們公司的編碼格式,這樣也就不用賦值了。
代碼已修正,感謝presia發現的bug,疏忽了。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://www.cnblogs.com/ZXdeveloper/archive/2017/11/07/7798943.html