您可以使用以下解决方案之一:
- BindableParameter(使用普通绑定、附加属性和MarkupExtension)
https://marlongrech.wordpress.com/2008/08/03/my-wish-came-true-i-can-now-use-databinding-in-a-converterparameter/
你需要集成类BindableParameter和BindableParameterExtension(如下所示),然后可以按照以下方式使用它:
在 XAML 中:
xmlns:local="clr-namespace:BindableParameterExtension"
<local:SampleConverter x:Key="sampleConverter" />
<StackPanel Orientation="Vertical">
<TextBox Name="txtContent" Text="Text from txtContent" />
<TextBox Name="txtParameter" Text="Text from txtParameter" />
<TextBox Name="txtBindingSample"
Text="{Binding ElementName=txtContent, Path=Text, Converter={StaticResource sampleConverter}}"
local:BindableParameter.BindParameter="{local:BindableParameter TargetProperty=TextBox.Text,
Binding={Binding ElementName=txtParameter, Path=Text} }" />
</StackPanel>
属性 "TargetProperty":
TargetProperty=TextBox.Text
BindableParameter的值必须设置为原始绑定属性(在本例中为"TextBox.Text")。
示例转换器:
using System;
using System.Windows.Data;
namespace BindableParameterExtension
{
public class SampleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null && parameter != null)
{
return value.ToString() + ", " + parameter.ToString();
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is string && parameter is string)
{
string text1 = value as string;
string textParamter = parameter as string;
return text1.Replace(textParamter, "");
}
return value;
}
}
}
该参数可用于“Convert”和“ConvertBack”方法(对于绑定到视图模型非常有用)。
类BindableParameter和BindableParameterExtension(URL见上面(不是我的代码))。
using System.Windows.Data;
using System.Windows.Markup;
namespace BindableParameterExtension
{
public class BindableParameter : Freezable
{
#region fields
private static FieldInfo isSealedFieldInfo;
#endregion
#region Properties
#region Parameter
public static readonly DependencyProperty ParameterProperty =
DependencyProperty.Register("Parameter", typeof(object), typeof(BindableParameter),
new FrameworkPropertyMetadata((object)null,
(d, e) =>
{
BindableParameter param = (BindableParameter)d;
param.ConverterParameterValue = e.NewValue;
InvalidateBinding(param);
}
));
public object Parameter
{
get { return (object)GetValue(ParameterProperty); }
set { SetValue(ParameterProperty, value); }
}
#endregion
#region BindParameter
public static readonly DependencyProperty BindParameterProperty =
DependencyProperty.RegisterAttached("BindParameter", typeof(BindableParameter), typeof(BindableParameter),
new FrameworkPropertyMetadata((BindableParameter)null,
new PropertyChangedCallback(OnBindParameterChanged)));
public static BindableParameter GetBindParameter(DependencyObject d)
{
return (BindableParameter)d.GetValue(BindParameterProperty);
}
public static void SetBindParameter(DependencyObject d, BindableParameter value)
{
d.SetValue(BindParameterProperty, value);
}
private static void OnBindParameterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement element = d as FrameworkElement;
if (element == null)
throw new InvalidOperationException("BindableParameter can be applied to a FrameworkElement only");
BindableParameter parameter = (BindableParameter)e.NewValue;
element.Initialized += delegate
{
parameter.TargetExpression = BindingOperations.GetBindingExpression(element, parameter.TargetProperty);
parameter.TargetBinding = BindingOperations.GetBinding(element, parameter.TargetProperty);
InvalidateBinding(parameter);
};
}
#endregion
public object ConverterParameterValue { get; set; }
public BindingExpression TargetExpression { get; set; }
public Binding TargetBinding { get; private set; }
public DependencyObject TargetObject { get; private set; }
public DependencyProperty TargetProperty { get; internal set; }
#endregion
static BindableParameter()
{
isSealedFieldInfo =
typeof(BindingBase).GetField("_isSealed", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (isSealedFieldInfo == null)
throw new InvalidOperationException("Oops, we have a problem, it seems like the WPF team decided to change the name of the _isSealed field of the BindingBase class.");
}
private static void InvalidateBinding(BindableParameter param)
{
if (param.TargetBinding != null && param.TargetExpression != null)
{
bool isSealed = (bool)isSealedFieldInfo.GetValue(param.TargetBinding);
if (isSealed)
isSealedFieldInfo.SetValue(param.TargetBinding, false);
param.TargetBinding.ConverterParameter = param.ConverterParameterValue;
if (isSealed)
isSealedFieldInfo.SetValue(param.TargetBinding, true);
param.TargetExpression.UpdateTarget();
}
}
#region Freezable Stuff
protected override Freezable CreateInstanceCore()
{
return this;
}
#endregion
}
[MarkupExtensionReturnType(typeof(BindableParameter))]
public class BindableParameterExtension : MarkupExtension
{
public DependencyProperty TargetProperty { get; set; }
public Binding Binding { get; set; }
public BindableParameterExtension(DependencyProperty property)
{
TargetProperty = property;
}
public BindableParameterExtension()
{ }
public override object ProvideValue(IServiceProvider serviceProvider)
{
_bindableParam = new BindableParameter();
BindingOperations.SetBinding(_bindableParam, BindableParameter.ParameterProperty, Binding);
_bindableParam.TargetProperty = TargetProperty;
return _bindableParam;
}
private BindableParameter _bindableParam;
}
}
- 对象引用:
http://drwpf.com/blog/2007/09/02/supplying-an-object-reference-in-the-constructorparameters-collection-of-an-objectdataprovider/
你必须集成ObjectReference类:
http://www.drwpf.com/blog/Portals/0/Code/ObjectReference.cs.txt
在XAML中:
xmlns:local="clr-namespace:WpfMarkupExtension"
<local:SampleConverter x:Key="sampleConverter" />
<StackPanel Orientation="Vertical">
<TextBox Name="txtContent" Text="Text from txtContent" />
<TextBox Name="txtParameter" Text="Text from txtParameter" local:ObjectReference.Declaration="{local:ObjectReference txtParam}" />
<TextBox Name="txtBindingSample"
Text="{Binding ElementName=txtContent, Path=Text,
Converter={StaticResource sampleConverter},
ConverterParameter={local:ObjectReference txtParam}}" />
</StackPanel>
这段代码:
local:ObjectReference.Declaration="{local:ObjectReference txtParam}"
创建一个静态字典中的引用和部分内容:
ConverterParameter={local:ObjectReference txtParam}}"
从字典中获取此对象引用-->这里没有绑定,字典是在解析时填充的。
示例转换器:
using System;
using System.Windows.Controls;
using System.Windows.Data;
namespace WpfMarkupExtension
{
public class SampleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null && parameter is TextBox)
{
return value.ToString() + ", " + ((TextBox)parameter).Text;
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is string && parameter is TextBox)
{
string text1 = value as string;
string textParamter = ((TextBox)parameter).Text;
return text1.Replace(textParamter, "");
}
return value;
}
}
}
3.
可绑定的转换器参数(使用自定义绑定语法):
http://www.codeproject.com/Articles/456589/Bindable-Converter-Parameter
在XAML中:
xmlns:local="clr-namespace:BcpBindingExtension"
<local:SampleConverter x:Key="sampleConverter" />
<StackPanel Orientation="Vertical">
<TextBox Name="txtContent" Text="Text from txtContent" />
<TextBox Name="txtParameter" Text="Text from txtParameter" />
<TextBox Name="txtBindingSample">
<TextBox.Text>
<local:BcpBinding Path="Text" ElementName="txtContent"
Converter="{StaticResource sampleConverter}"
ConverterParameters="Binding Path=Text ElementName=txtParameter"
Mode="TwoWay"/>
</TextBox.Text>
</TextBox>
</StackPanel>
示例转换器:
using System;
using System.Windows.Data;
namespace BcpBindingExtension
{
public class SampleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null && parameter is object[] && ((object[])parameter).Length > 0)
{
return value.ToString() + ", " + ((object[])parameter)[0].ToString();
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is string && parameter is object[] && ((object[])parameter).Length > 0)
{
string text1 = value as string;
string textParamter = ((object[])parameter)[0] as string;
return text1.Replace(textParamter, "");
}
return value;
}
}
}