WPF学习资料
http://www.cnblogs.com/Jax/category/88715.html
http://archive.msdn.microsoft.com/wpfsamples (常用实例)
http://msdn.microsoft.com/zh-cn/library/ms752299.aspx
http://www.cnblogs.com/jv9/category/167735.html (强悍学习站)
//---------------------------------------------
一个通用的WPF值转换器
在WPF中应用数据绑定时经常需要做一些简单的逻辑判断。
比如ViewModel中有一个HasError(布尔值)的属性表示是否有错误。我需要将它绑定于Button的IsEnable属性上,即:当没有错误时Button可用。这时就需要将HasError取反。WPF默认的绑定引擎是不支持的。
还有一种情况比如ViewModel中有一个Sex(int值)的属性表示性别,我需要将它绑定到TextBlock上,当值为1时显示男,值为2时显示女。WPF默认绑定也是不支持这种判断的。
于是一个通用的值转换器就诞生了,用法如下:
<Button IsEnabled="{Binding HasError, Converter={StaticResource GenericTypeConverter}, ConverterParameter='IsReverse=True'}">OK</Button>
IsReverse参数表示是否取返,如果转换的值为true则变为false,反之亦然。
<TextBlock Text="{Binding Sex, Converter={StaticResource GenericTypeConverter}, ConverterParameter='Alias=1:男|2:女|other:未知'}" />
Alias参数表示将值映射为字符串,other表示当遇到没有指定的值时显示的文本
另外bool to Visibility的转换可以自动进行,不需要指定参数。
有意见欢迎指正
完整代码如下:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Windows;
namespace MoodSunshiny.WPF.Converter
{
/// <summary>
/// 一个通用的类型转换器,可以提供更多转换控制参数
/// </summary>
public class GenericTypeConverter : IValueConverter
{
/// <summary>
/// 是否反转转换源参数值
/// 仅对bool类型的值有效
/// </summary>
private bool IsReverse { get; set; }
/// <summary>
/// 用于将转换结果映射为其它字符串
/// 例如:Alias=True:是|False:否
/// </summary>
private Dictionary<object, string> Alias { get; set; }
/// <summary>
/// 解析转换参数
/// </summary>
private void AnalyseConvertParameter(string convertParameter)
{
/*设置参数默认值*/
IsReverse = false;
Alias = null;
if (!string.IsNullOrEmpty(convertParameter))
{
var pkvs = convertParameter.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var pkv in pkvs)
{
var pkvo = pkv.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
if (pkvo.Length != 2)
throw new NotSupportedException("不支持设置:" + pkv);
var pk = pkvo[0].Trim();
var pv = pkvo[1].Trim();
switch (pk)
{
case "IsReverse":
bool b;
if (!bool.TryParse(pv, out b))
throw new NotSupportedException("参数取值错误:" + pkv);
else
IsReverse = b;
break;
case "Alias":
{
Alias = new Dictionary<object, string>();
var dfkvs = pv.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var dfkv in dfkvs)
{
var dfkvo = dfkv.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
if (dfkvo.Length != 2)
throw new NotSupportedException("不支持设置:" + dfkvo);
var dfk = dfkvo[0].Trim();
var dfv = dfkvo[1].Trim();
object oKey = null;
int i;
if (dfk.Equals("true", StringComparison.OrdinalIgnoreCase))
oKey = true;
else if (dfk.Equals("false", StringComparison.OrdinalIgnoreCase))
oKey = false;
else if (dfk.Equals("other", StringComparison.OrdinalIgnoreCase))
oKey = "other";
else if (int.TryParse(dfk, out i))
oKey = i;
else
throw new NotSupportedException("参数取值错误:" + dfkv);
Alias[oKey] = dfv;
}
}
break;
default:
throw new NotSupportedException("不支持的参数名:" + pk);
}
}
}
}
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
AnalyseConvertParameter(parameter as string);
try
{
var sourceType = value.GetType();
if (IsReverse && sourceType == typeof(bool))
value = !((bool)value);
if (targetType == typeof(string))
{
if (Alias != null && Alias.ContainsKey(value))
return Alias[value];
else if (Alias != null && Alias.ContainsKey("other"))
return Alias["other"];
else
return value == null ? "" : value.ToString();
}
if (targetType == typeof(bool))
{
if (sourceType == typeof(Visibility))
return (Visibility)value == Visibility.Visible;
}
else if (targetType.IsEnum)
{
if (sourceType == typeof(bool) && targetType == typeof(Visibility))
{
return (bool)value ? Visibility.Visible : Visibility.Collapsed;
}
else
{
return Enum.Parse(targetType, value.ToString(), true);
}
}
else
{
return System.Convert.ChangeType(value, targetType);
}
return System.Convert.ChangeType(value, targetType);
}
catch
{
return null;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Convert(value, targetType, parameter, culture);
}
}
}
//-----------------------------------------------------
WPF:Data
Binding 数据绑定基础(2)
是一个建立应用界面和业务逻辑之间联系的一个过程。
被绑定的两者(界面和数据)是相互影响的(反映和记录对方的变化)。
绑定静态资源(资源在同一个XAML文件中,注意一定要放到最上边,紧随<Window>之后)
<Window
xlmns:system="clr-namespace:assembly=mscorlib">
<Window.Resources>
<system.String
x:Key="MenuFileHeader">File</system:String>
</Window.Resources>
<Grid><Menu><MenuItem
Header={StaticResource
MenuFileHeader}></MenuItem></Menu></Grid>
</Window>
绑定静态资源(资源放在独立的资源文件中:<HOME>"Resources"Skins"Default.xaml)
<ResourceDictionary
xlmns:system="clr-namespace:assembly=mscorlib">
<system:String
x:Key="WindowMainTitle>Window Main
Title</system:String>
</ResourceDictionary>
...
...
在Application.xaml中引用所定义的资源文件(当然,你可以直接在这里定义资源)
<Application>
<Application.Resources>
<ResourceDictionary
Source="Resources/Skins/Default.xaml"></ResourceDictionary>
</Application>
...
...
<Window Title={StaticResource
WindowMainTitle}>
</Window>
绑定动态资源(资源在独立的资源文件中,并被通过动态装载,参见我的WPF:换肤基础)
<ResourceDictionary
xlmns:system="clr-namespace:assembly=mscorlib">
<system:String
x:Key="DynamicWindowMainTitle></system:String>
</ResourceDictionary>
...
...
<Window Title={DynamicResource
WindowMainTitle}>
</Window>
绑定类对象属性(参见我的WPF:数据绑定基础)
绑定数据集(DataSet)
xxx.XAML
<Window>
<Grid>
<TextBox Text="{Binding
Path=Table.UserName}"/>
</Grid>
</Window>
xxx.XAML.CS
DataSet
dsUserInfo = GetUserInfo();
//默认Table[0]的名字是"Table",所以上面的Path是Table.xxx
DataContext =
dsUserInfo;
数据绑定的能力还有很多,今天先到这里,休息,休息一下。
WPF
阅读全文
邮箱:steven9801@163.com
QQ: 48039387