0

我有一个用户控件,具有以下(简化)布局:

<UserControl x:Name="FV">
 <DockPanel LastChildFill="False">
  <StackPanel DockPanel.Dock="Left">
    ... some content, let's say customer name ...
  </StackPanel>
  <MyButton DockPanel.Dock="Left"
    Visibility="{Binding Path=IsMouseOver, ElementName=FV, Converter={StaticResource boolToVisibilityConverter}}">
  </MyButton>
 </DockPanel>
</UserControl>

所以基本上它会显示一个文本,并将一个编辑按钮悬停在该文本的右侧。

现在我将此控件用作树中的 ItemTemplate。

问题来自于长名称。在这种情况下,树会水平滚动,并且 UserControl 在逻辑上向右延伸,我的按钮不再可见。

text1 (edit)  |
text22 (edit) |
vverylongtext |

我想用我的按钮重叠悬停时的verylongtext:

text1 (edit)  |
text22 (edit) |
vverylo(edit) |

我怎样才能做到这一点?我的 UserControl 不知道它的使用位置,因此不知道父元素的 ActualWidth。

4

2 回答 2

0

我完全按照你的要求做了。UserControl我用一个TextBlock和创建了一个Button。如果输入的文本TextBlock很长,则Button仍然看不见,这MouseOver完全符合您的需要。但是,如果输入的文本TextBlock足够小,则Button仍然可见。

注意HorizontalAlignment = Left必须设置在Button.

Window3.xaml

<Window x:Class="WpfStackOverflow.Window3"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:uc="clr-namespace:WpfStackOverflow"
        Title="Window3" Height="300" Width="300" SizeToContent="WidthAndHeight">

    <StackPanel>
        <uc:UserControl1 Width="200" Height="35"/>
    </StackPanel>

</Window>

UserControl.1.xaml

<UserControl x:Class="WpfStackOverflow.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             xmlns:local="clr-namespace:WpfStackOverflow"
             Background="Bisque"
             Height="25">       

    <StackPanel x:Name="DckPnl" Height="25" Orientation="Horizontal">
        <TextBlock x:Name="Tb" MouseEnter="Tb_MouseEnter_1" MouseLeave="Tb_MouseLeave_1" FontFamily="Arial" Text="some content , let's say customer name some content, let's say customer name" Background="AliceBlue"/>
        <Button x:Name="Btn" Visibility="Hidden" Content="Edit" Width="35" Height="25" Margin="0 0 0 0" HorizontalAlignment="Left"/>
    </StackPanel>

</UserControl>

UserControl1.xaml.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace WpfStackOverflow
{
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }

        private void Tb_MouseEnter_1(object sender, MouseEventArgs e)
        {
            Thickness newMargin = new Thickness();

            FormattedText f = new FormattedText(Tb.Text,
                                                new System.Globalization.CultureInfo("en-US"),
                                                System.Windows.FlowDirection.LeftToRight,
                                                new Typeface("Arial"),
                                                Tb.FontSize, Brushes.Black);
            if (f.Width > this.ActualWidth)
                newMargin = new Thickness((this.ActualWidth - f.Width) - Btn.ActualWidth, 0, 0, 0);
            else
                newMargin = Btn.Margin;

            Btn.Margin = newMargin;
            Btn.Visibility = System.Windows.Visibility.Visible;
        }

        private void Tb_MouseLeave_1(object sender, MouseEventArgs e)
        {
            Btn.Margin = new Thickness(0, 0, 0, 0);
            Btn.Visibility = System.Windows.Visibility.Hidden;
        }
    }   
}
于 2016-09-23T15:19:59.397 回答
0

要将按钮放置在文本上,您可以使用 AdornerLayer、Z-Index、Tooltip 或 Popup。最后一个在我看来是最简单的解决方案。这是一个如何使用弹出窗口完成的示例:

<StackPanel Margin="0 20 0 0" Name="StackPanel" Width="100">
    <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
        <ScrollViewer.Resources>
            <wpfApplication1:OrConverter x:Key="OrConverter" />
        </ScrollViewer.Resources>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="longlonglonglongtextlonglonglonglongtextlonglonglonglongtext" />
            <Popup x:Name="Popup" StaysOpen="True"
                   PlacementTarget="{Binding ElementName=StackPanel}"
                   Placement="Right"
                   HorizontalOffset="-20"> <!--here you can bind to button's width instead of static value-->
                <Popup.IsOpen>
                    <MultiBinding Converter="{StaticResource OrConverter}">
                        <Binding ElementName="StackPanel" Path="IsMouseOver" Mode="OneWay" />
                        <Binding ElementName="Popup" Path="IsMouseOver" Mode="OneWay" />
                    </MultiBinding>
                </Popup.IsOpen>
                <Button Name="Button" Content="X" Height="16" Width="20" VerticalAlignment="Top" />
            </Popup>
        </StackPanel>
    </ScrollViewer>
</StackPanel>

OrConverter 可以在这个答案中找到。

看起来像这样

于 2016-09-23T12:13:33.237 回答