背景 數據庫
本文經過一個簡單的按鈕權限來描述如何使用IValueConverter接口。 數組
首先能夠看到IValueConverter包含兩個接口方法: 數據庫設計
object Convert(object value, Type targetType, object parameter, CultureInfo culture); 性能
以及 this
object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture); spa
實現了源數據類型以及目標數據類型之間的轉換。 設計
詳細分析 xml
1. 該按鈕權限分爲4種狀態:查詢,修改,添加,刪除;用戶的權限能夠是4種狀態中的任意組合; blog
好比3級用戶只擁有查詢的權限;2級用戶擁有查詢和修改的權限;超級管理員擁有全部狀態的權限; 繼承
UI上的顯示很簡單,若是有權限,按鈕則顯示;無權限,按鈕就不顯示;
2. 有些人考慮這個問題的時候,可能會想到在數據庫設計這個權限的時候,會使用字符串形式,如「1」表示擁有查詢權限,「1,3」表示擁有查詢和添加權限,「1,2,3,4」表示擁有全部權限。而我這裏考慮是採用位運算的方式進行處理;考慮到4種狀態,我先建立一個用戶權限枚舉類型
代碼
///
<summary>
///
用戶權限
///
</summary>
public
enum
UserRight
{
None
=
0
,
///
<summary>
///
查詢權限(1)
///
</summary>
Select
=
1
,
///
<summary>
///
修改權限(2)
///
</summary>
Update
=
2
,
///
<summary>
///
插入權限(3)
///
</summary>
Insert
=
3
,
///
<summary>
///
刪除權限(4)
///
</summary>
Delete
=
4
}
根據4種狀態的組合,能夠獲得15種狀況的組合;因此經過1—15整型數值,能夠對應每一種的組合狀況,這樣能夠經過一個枚舉擴展方法進行實現:
代碼
///
<summary>
///
將複合權限類型ID 轉換成 權限枚舉類型數組
///
</summary>
///
<param name="userRightComplex"></param>
///
<returns></returns>
public
static
UserRight[] ToUserRightArray(
this
int
userRightComplex)
{
int
max
=
EnumHelper.GetValues(
typeof
(UserRight)).Length
-
2
;
//
除去None枚舉,並須要再減1,因此減2
List
<
UserRight
>
userRightList
=
null
;
while
(userRightComplex
>
0
)
{
if
(userRightList
==
null
)
userRightList
=
new
List
<
UserRight
>
();
int
arg
=
Convert.ToInt32(Math.Pow(
2
, max));
if
(userRightComplex
>=
arg)
{
userRightComplex
-=
arg;
userRightList.Add((UserRight)Enum.Parse(
typeof
(UserRight), (max
+
1
).ToString(),
true
));
}
max
--
;
}
if
(userRightList
==
null
||
userRightList.Count
==
0
)
{
return
null
;
}
return
userRightList.ToArray();
}
這樣,經過一個整型值能夠獲得一個用戶權限的數組。
如1獲得一個「查詢」數組,5獲得一個「查詢、添加」數組,15獲得全部狀態的數組;
這樣作的目的是爲了對於用戶權限表能夠減小數據庫數據存儲量,以及可以提升數據庫查詢的性能;
3. 添加一個UserRightControl類,用於用戶數據傳遞:
代碼
public
class
UserRightControl
{
///
<summary>
///
複合權限類型ID
///
</summary>
public
int
UserRightComplex {
get
;
set
; }
///
<summary>
///
權限數組
///
</summary>
private
UserRight[] _rights;
public
UserRight[] UserRights
{
get
{
if
(_rights
==
null
)
{
//
將複合權限類型ID 轉換成 權限枚舉類型數組
_rights
=
UserRightComplex.ToUserRightArray();
}
return
_rights;
}
}
}
4. 建立一個繼承於IValueConverter接口的UserRightConverter
代碼
public
class
UserRightConverter : IValueConverter
{
public
object
Convert(
object
value, Type targetType,
object
parameter, CultureInfo culture)
{
Visibility visibility
=
Visibility.Collapsed;
UserRight[] rightArray
=
(UserRight[])value;
UserRight right
=
(UserRight)Enum.Parse(
typeof
(UserRight), (
string
)parameter,
true
);
UserRight state
=
rightArray.FirstOrDefault(o
=>
o
==
right);
if
(state
!=
UserRight.None)
{
visibility
=
Visibility.Visible;
}
return
visibility;
}
public
object
ConvertBack(
object
value, Type targetType,
object
parameter, CultureInfo culture)
{
throw
new
NotImplementedException();
}
}
其中value是做爲一個用戶權限數組綁定過來的,parameter做爲對應按鈕的屬性參數,若是value包含了parameter,該按鈕就顯示。
5. 接着,建立一個UserRightButton.xaml的用戶權限按鈕控件:
代碼
<
UserControl
x:Class
="SilverlightAppDemo.UserRightButton"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation%22
xmlns:x="
http://schemas.microsoft.com/winfx/2006/xaml%22
xmlns:uc
="clr-namespace:SilverlightAppDemo"
>
<
UserControl.Resources
>
<
uc:UserRightConverter
x:Key
="userRightConverter"
/>
<
Style
x:Key
="userright"
TargetType
="Button"
>
<
Setter
Property
="Height"
Value
="30"
/>
<
Setter
Property
="Width"
Value
="60"
/>
<
Setter
Property
="FontSize"
Value
="14"
/>
</
Style
>
</
UserControl.Resources
>
<
StackPanel
HorizontalAlignment
="Left"
>
<
StackPanel
Orientation
="Horizontal"
>
<
Button
Content
="查詢"
Visibility
="{Binding UserRights, Converter={StaticResource userRightConverter}, ConverterParameter=Select}"
Style
="{StaticResource userright}"
></
Button
>
<
Button
Content
="修改"
Visibility
="{Binding UserRights, Converter={StaticResource userRightConverter}, ConverterParameter=Update}"
Style
="{StaticResource userright}"
></
Button
>
<
Button
Content
="添加"
Visibility
="{Binding UserRights, Converter={StaticResource userRightConverter}, ConverterParameter=Insert}"
Style
="{StaticResource userright}"
></
Button
>
<
Button
Content
="刪除"
Visibility
="{Binding UserRights, Converter={StaticResource userRightConverter}, ConverterParameter=Delete}"
Style
="{StaticResource userright}"
></
Button
>
</
StackPanel
>
</
StackPanel
>
</
UserControl
>
該用戶控件用於權限按鈕的UI顯示,注意到Button的Visibility屬性,Binding UserRight 綁定了 UserRightControl類中的UserRights的權限數組;Converter={StaticResource userRightConverter} 將以userRightConverter爲Key的UserRightConverter類 做爲按鈕的轉換器,ConverterParameter後面的值爲parameter。
6. 最後,在Page.xaml上添加用戶權限按鈕控件:
代碼
<
UserControl
x:Class
="SilverlightAppDemo.Page"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation%22
xmlns:x="
http://schemas.microsoft.com/winfx/2006/xaml%22
xmlns:uc
="clr-namespace:SilverlightAppDemo"
>
<
UserControl.Resources
>
<
uc:UserRightControl
UserRightComplex
="1"
x:Key
="urControl"
/>
</
UserControl.Resources
>
<
StackPanel
>
<
uc:UserRightButton
x:Name
="btnUserRight"
DataContext
="{StaticResource urControl}"
/>
</
StackPanel
>
</
UserControl
>
其中UserRightButton中的DataContext屬性綁定了以urControl爲Key的UserRightControl。
7. 運行下程序
當UserRightComplex爲1時,
當UserRightComplex爲5時,
當UserRightComplex爲15時,
本文主要介紹如何使用IValueConverter在應用場景中,歡迎繼續交流。
源代碼下載:SilverlightAppDemo.rar