我在嘗試寫一個顯示本機 WIFI 熱點的賬號和密碼的控件,要求此控件在有限的空間內顯示。但是盡可能顯示出熱點的賬號和密碼。而熱點的賬號和密碼是用戶配置的,也許長度很長。我的需求是在假如賬號的長度較短的時候,將剩余的空間盡可能給到密碼的顯示。反過來,在密碼長度比較短的時候,將剩余的空間給到賬號的顯示。如果兩者的長度都比較長,那么同時限制兩者的最大尺寸
有以下的不同的情況的需求
- 賬號和密碼的長度都較短,可以完全顯示
- 賬號較長,密碼較短,但合起來的長度小於最大尺寸。期望能完全顯示出來
- 賬號超長,可以限制賬號顯示的最大長度
- 賬號超長,密碼較長,將會因為限制最大尺寸,而裁剪賬號和密碼顯示內容
- 賬號較短,密碼較長,可以讓密碼占用更多的空間
- 如果賬號還沒達到限制的最大寬度,密碼超長,那么裁剪密碼內容
也就是說需要相當於在 Grid 里面造兩個可以撐開的 *
長度的,但是限制最大尺寸的布局。不過本文將用另一個方法,采用 StackPanel 加上轉換器來實現
先給 StackPanel 設置最大的寬度尺寸,接着設置 StackPanel 采用水平布局的方式。當然了本文的方法對於垂直布局也是生效的,只需要大家將對應的水平布局修改為垂直布局即可
<StackPanel x:Name="OuterStackPanel" MaxWidth="300" Orientation="Horizontal">
</StackPanel>
在 StackPanel 里面放入必要的控件,其中對於賬號的內容顯示,只需要設置 MaxWidth 最大寬度即可。因為總的寬度計算是依靠 StackPanel 進行限制,而賬號內容顯示的控件的尺寸,是依靠后面的密碼顯示控件控制的
<StackPanel x:Name="OuterStackPanel" MaxWidth="300" Orientation="Horizontal">
<TextBlock x:Name="SSIDTextBlock" d:Text="熱點:" Text="熱點:" FontSize="14" />
<TextBlock x:Name="SSIDContentTextBlock" d:Text="SSID" Text="{Binding ElementName=NameTextBox,Path=Text}" FontSize="14" MaxWidth="150" TextTrimming="CharacterEllipsis" />
<TextBlock x:Name="SpaceTextBlock" Text=" " FontSize="14" />
</StackPanel>
通過 SpaceTextBlock 控件,用來分割距離
接着就是加上,密碼顯示模塊。在密碼顯示里面,傳入 OuterStackPanel 里面,除了 SSIDContentTextBlock 綁定賬號內容的空間外的其他控件的尺寸,用來計算剩余給 賬號內容顯示控件 和 密碼內容顯示控件 的總空間。再通過設置自身的最大空間占用值,即可在 賬號內容顯示控件 沒有占用較多空間時,盡可能撐開 密碼內容顯示控件 大小
<TextBlock x:Name="PasswordTextBlock" d:Text="密碼:" Text="密碼:" FontSize="14" />
<TextBlock x:Name="PasswordContentTextBlock" Grid.Column="4" d:Text="Password" Text="{Binding ElementName=KeyTextBox,Path=Text}" FontSize="14" TextTrimming="CharacterEllipsis">
<TextBlock.MaxWidth>
<MultiBinding Converter="{StaticResource MirrorPopupContentPasswordMaxWidthConverter}">
<Binding ElementName="OuterStackPanel" Path="MaxWidth"/>
<Binding ElementName="SSIDTextBlock" Path="ActualWidth"/>
<Binding ElementName="SSIDContentTextBlock" Path="ActualWidth"/>
<Binding ElementName="SpaceTextBlock" Path="ActualWidth"/>
<Binding ElementName="PasswordTextBlock" Path="ActualWidth"/>
</MultiBinding>
</TextBlock.MaxWidth>
</TextBlock>
以上的 MirrorPopupContentPasswordMaxWidthConverter 的代碼定義如下
public class MirrorPopupContentPasswordMaxWidthConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values[0] is double total)
{
// 一下的 Skip 傳入 1 表示的是跳過第 1 個控件的寬度計算
// 第 1 個控件是賬號內容顯示控件
foreach (var val in values.OfType<double>().Skip(1))
{
total -= val;
}
return total > 0 ? total : 0;
}
return DependencyProperty.UnsetValue;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
通過此方式即可實現在有限的空間內,讓兩個元素盡可能撐開
特別感謝 lsj 提供的方法
可以通過如下方式獲取本文的源代碼,先創建一個空文件夾,接着使用命令行 cd 命令進入此空文件夾,在命令行里面輸入以下代碼,即可獲取到本文的代碼
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 87fb070b57a1d4364f7c460d7f33c20545974dd0
以上使用的是 gitee 的源,如果 gitee 不能訪問,請替換為 github 的源
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
獲取代碼之后,進入 NawhejefurWheekaijerehu 文件夾