问题遇到的现象和发生背景
要求:Grid.ColumnDefinition.Width需要随着窗口大小变化而变化,需求是Grid.ColumnDefinition.Width=Window.Width*0.382。
下面代码col0是Grid第一列的Name
col0.SetBinding(ColumnDefinition.WidthProperty, new Binding("Width"){ Source = this,ConverterParameter= "({0}*0.382)",Converter=new DTEvalConvert() });
DTEvalConvert是利用DataTable来实现表达式的转换器
///
/// 使用DataTalbe.Compute
///
public class DTEvalConvert : IValueConverter
{
static System.Data.DataTable dt = new System.Data.DataTable();
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(parameter != null)
{
string expression = parameter.ToString().Replace("{0}",value.ToString());
var r = dt.Compute(expression, "");
return r;
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}
运行结果及报错内容
当窗体改变大小时,发现Col0.Width没跟着改变,其值一固定。
通过断点 var r = dt.Compute(expression, ""); 发现启动运行,窗体实例建立后,DTEvalConvert .Convert 会执行一次,object value的值是A
当点击窗体最大化后,DTEvalConvert .Convert 会执行2次,第一次参数object value的值是当前窗体正确的新宽度B,
第二次传入object value 窗体旧宽度B.
因为有第二次传入,导致Col0.Width无法达到预期值。目前不知绑定为啥会执行2次。
在给winndow.SizeChanged实现事件函数,在Window_SizeChanged设置断点调试,发现点击窗体最大化后,先执行2次DTEvalConvert .Convert,再执行在Window_SizeChanged。这样更改col0宽度可以写在SizedChanged里面,那么col0的绑定变得毫无意义。
请问如果不在Window_SizeChanged写实现,如何解决DTEvalConvert .Convert 会执行2次并在第二次传入旧值的原因。