我想用自定义的两行UserControl在WPF(C#-MVVM)中制作一个ToolTip

在 View 中,我有一个带有ListBox和自定义ItemSourceItemTemplate,可在其中设置上一个ToolTip,该string在运行时仅显示第一行,而第二个是空ToolTip。确实,问题在于MultiBinding的第二行,其中我将try/catch与转换器一起使用。 string失败的转换器,返回一个空的null

我知道异常是由一个int值生成的,而它应该是一个不能为空的null,但是我不明白为什么。
编辑:我说DependencyProperty UnsetValue是错误的;问题是转换器由于Value引发强制转换异常,我不知道为什么。

这里转换器代码:

public class FromDecimal_MVConverter : Base_MVConverter
{
    public override object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        try
        {
            // Default are 2 decimals
            if (values.Length == 2)
            {
                int decimals;
                switch ((int)values[1])
                {
                    case int dec when dec < 0:
                        decimals = 0;
                        break;
                    case int dec when dec > 99:
                        decimals = 99;
                        break;
                    default:
                        decimals = (int)values[1];
                        break;
                }
                return ((decimal)values[0]).ToString("N" + decimals.ToString());
            }
            else
            {
                return ((decimal)values[0]).ToString("N2");
            }
        }
        catch
        {
            return string.Empty;
        }
    }

    public override object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

这里 XAML 代码:
...
<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>
...

如您所见,ObservableCollection ValuesDecimals中对象的属性。 ValuesDecimals是代码后面的属性,与它们的依赖项属性相关联。

这里TextBlock的定义:
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); }
}

我不明白为什么ToolTip之外的ToolTip可以工作,为什么在ojit_code内不起作用。
我该如何解决该问题?

最佳答案

绑定(bind)失败,因为UserControl不是ToolTip的视觉祖先。

您可以将TagGrid属性绑定(bind)到Decimals属性,然后使用TagPlacementTarget属性绑定(bind)到ToolTip属性:

<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>

关于c# - WPF-具有MultiBinding和不同DataContext的自定义工具提示,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59896105/

10-12 14:12