C# WPF-具有多重绑定和不同数据上下文的自定义工具提示
我想在WPF(C#-MVVM)中创建一个带有自定义两行工具提示的C# WPF-具有多重绑定和不同数据上下文的自定义工具提示,c#,wpf,mvvm,data-binding,C#,Wpf,Mvvm,Data Binding,我想在WPF(C#-MVVM)中创建一个带有自定义两行工具提示的UserControl 在视图中,我有一个列表框,其中包含一个ItemSource和一个自定义ItemTemplate,用于设置上一个工具提示,在运行时只显示第一行,而第二行是空的字符串。实际上,问题是工具提示的第二行,其中我使用了带转换器的多绑定;在try/catch中失败的转换器返回空字符串 我知道异常是由一个null的值生成的,而它应该是一个int不可为null的值,但我不明白为什么。 编辑:我说错了null;问题是转换器触发
UserControl
在视图中,我有一个列表框
,其中包含一个ItemSource
和一个自定义ItemTemplate
,用于设置上一个工具提示
,在运行时只显示第一行,而第二行是空的字符串
。实际上,问题是工具提示的第二行
,其中我使用了带转换器的多绑定
;在try/catch
中失败的转换器返回空字符串
我知道异常是由一个null
的值生成的,而它应该是一个int
不可为null的值,但我不明白为什么。编辑:我说错了
null
;问题是转换器触发强制转换异常是因为dependencProperty UnsetValue
,我不知道为什么
此处转换器代码:
我不明白为什么文本块
在工具提示
之外有效,为什么在工具提示
内部无效。
如何解决此问题?绑定失败,因为
UserControl
不是工具提示的可视祖先
您可以将网格
的标记
属性绑定到小数
属性,然后使用工具提示
的放置目标
属性绑定到标记
属性:
<DataTemplate>
<Grid Tag="{Binding Decimals, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}">
<Grid.ToolTip>
<ToolTip>
<StackPanel>
<TextBlock Text="{Binding Description}"/>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{cv_ToString:FromDecimal_MVConverter}">
<Binding Path="Value"/>
<Binding Path="PlacementTarget.Tag" RelativeSource="{RelativeSource FindAncestor, AncestorType=ToolTip}"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</ToolTip>
</Grid.ToolTip>
...
</Grid>
</DataTemplate>
...
我是如何解决的:
我已经阅读了@Sinatr的评论,最后我发现了如何避免这个问题。
...
...
...
在这种情况下,BindingProxy
直接绑定到dependencProperty小数
,而不是DataContext
还是不行!你能解释一下你的第一行吗?如果我有多个属性,如何避免问题?如果我只能有一个标记?@MaxAquila,附加的依赖属性可能会有所帮助。另一种可能是使用,这种技术允许您命名和访问多个数据上下文。@Sinatr,谢谢,我已经解决了BindingProxy
@MaxAquila的问题,虽然很小,但很重要:请将答案作为单独的帖子发布。是的。
...
<ListBox ItemsSource="{Binding Values, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<ToolTipService.ToolTip>
<StackPanel>
<TextBlock Text="{Binding Description}"/>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{cv_ToString:FromDecimal_MVConverter}">
<Binding Path="Value"/>
<Binding Path="Decimals" RelativeSource="{RelativeSource FindAncestor, AncestorType=UserControl}"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</ToolTipService.ToolTip>
<TextBlock Foreground="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}">
<TextBlock.Text>
<MultiBinding Converter="{cv_ToString:FromDecimal_MVConverter}">
<Binding Path="Value"/>
<Binding Path="Decimals" RelativeSource="{RelativeSource FindAncestor, AncestorType=UserControl}"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
...
public static readonly DependencyProperty DecimalsProperty = DependencyProperty.RegisterAttached("Decimals", typeof(int), typeof(ucMyUserControl), new FrameworkPropertyMetadata(2) { BindsTwoWayByDefault = true });
public int Decimals
{
get { return (int)GetValue(DecimalsProperty); }
set { SetValue(DecimalsProperty, value); }
}
<DataTemplate>
<Grid Tag="{Binding Decimals, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}">
<Grid.ToolTip>
<ToolTip>
<StackPanel>
<TextBlock Text="{Binding Description}"/>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{cv_ToString:FromDecimal_MVConverter}">
<Binding Path="Value"/>
<Binding Path="PlacementTarget.Tag" RelativeSource="{RelativeSource FindAncestor, AncestorType=ToolTip}"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</ToolTip>
</Grid.ToolTip>
...
</Grid>
</DataTemplate>
<UserControl.Resources>
<local:BindingProxy x:Key="BP_Decimals" Data="{Binding Decimals, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"/>
</UserControl.Resources>
...
<DataTemplate>
<Grid>
<Grid.ToolTip>
<StackPanel>
<TextBlock Text="{Binding Description}"/>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{cv_ToString:FromDecimal_MVConverter}">
<Binding Path="Value"/>
<Binding Path="Data" Source="{StaticResource BP_Decimals}"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</Grid.ToolTip>
...
</Grid>
</DataTemplate>
...