不可能将值绑定到ConverterParametr
的{{1}}。只能在Binding
中的Binding
上设置DependencyProperty
。
我很好奇将DependencyObject
转换器实现为IValueConverter
。
DependencyObject
让我们在示例视图中查看吧。
public class AddConverter : DependencyObject, IValueConverter
{
public static readonly DependencyProperty AddIntegerProperty =
DependencyProperty.Register(nameof(AddInteger),
typeof(int),
typeof(AddConverter),
new PropertyMetadata(0));
public int AddInteger
{
get => (int)GetValue(AddIntegerProperty);
set => SetValue(AddIntegerProperty, value);
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (!(value is int intValue)) return 0;
return intValue + AddInteger;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
int intValue;
try
{
intValue = System.Convert.ToInt32(value);
}
catch (Exception)
{
return 0;
}
return intValue - AddInteger;
}
}
结果是<TextBox>
<TextBox.Text>
<Binding Path="MyIntegerProperty">
<Binding.Converter>
<local:AddConverter AddInteger="{Binding MyAddIntegerProperty, Mode=OneWay}" />
</Binding.Converter>
</Binding>
</TextBox.Text>
</TextBox>
仍返回默认值。通过提供的AddInteger
AddInteger
依赖属性没有变化的原因是什么?
脚注:由于Binding
方法仅由控件提供的值组成,因此MultiBinding
对我没有帮助。这些东西也应该在ViewModel中解决,但是我很好奇转换器的解决方案。
答案 0 :(得分:1)
问题是,首先,转换器无法继承其所在的DataContext,因此绑定无法正常工作:如果在VS上进行跟踪,您将在VS输出中看到“找不到框架导师”您拥有的绑定(请参阅附录A)。这也是为什么不能仅从FrameworkElement派生并使用 export const getChannels = () => dispatch => {
const token = "token";
axios
.get(`https://slack.com/api/conversations.list?token=${token}`)
.then(response => {
dispatch({
type: actionTypes.GET_CHANNELS,
payload: response.data
})
});
};
};
的原因:您不在可视化树中。没有祖先。同样,即使有框架指导者,DependencyObject也不能提供绑定的源。来源必须明确。仅继承自FrameworkElement的类可以继承DataContext。
因此,我偷了BindingProxy类(from this answer),并使用该类为绑定提供了源。这有点笨拙,但是我想到的另一种选择是从Freezable继承转换器,从本质上赋予它BindingProxy的属性,并在资源中创建转换器。它起作用了,但是我更喜欢这种组织方式。
RelativeSource={RelativeSource AncestorType=Whatever}
XAML
public class BindingProxy : Freezable
{
#region Overrides of Freezable
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
#endregion
#region Data Property
public Object Data
{
get { return (Object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register(nameof(Data), typeof(Object), typeof(BindingProxy),
new PropertyMetadata(null));
#endregion Data Property
}
<StackPanel.Resources>
<local:BindingProxy
x:Key="VMProxy"
Data="{Binding}"
/>
</StackPanel.Resources>
<TextBlock>
<TextBlock.Text>
<Binding Path="MyIntegerProperty">
<Binding.Converter>
<local:AddConverter
AddInteger="{Binding Data.MyAddIntegerProperty, Source={StaticResource VMProxy}}"
/>
</Binding.Converter>
</Binding>
</TextBlock.Text>
</TextBlock>
AddInteger="{Binding MyAddIntegerProperty, Mode=OneWay,
PresentationTraceSources.TraceLevel=High}"