WPF小知识 - 技巧合集

本文记录了解决WPF编程中的控件样式调整(Label自动换行、TextBlock和FlowDocument的布局)、远程控制界面问题、窗口定位、列表菜单操作、状态栏设置以及图片更换和跨线程UI更新的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在编写WPF程序遇到一些小问题,所以记录起来,查其他方便。
我的所有技巧合集文章都会不定期更新里面的内容,对一些小的知识点和技巧进行更新。

在这里插入图片描述

Label自动换行

网上搜的都不能自动换行,发现使用Run 就可以。在脚本中直接调用labTip.Text进行赋值就可以了。

<Label Foreground="#FF9E9E9E" FontSize="16" Margin="33,398,212,48" >
    <TextBlock TextWrapping="Wrap" Margin="0 10 0 10" ><Run Name="labTip" Text="x"/></TextBlock>
</Label>

在ToDesk远控下无法显示界面

可以关闭硬件加速,在窗体的Loaded后执行下面的代码。

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    var hwnd_source = (System.Windows.Interop.HwndSource)PresentationSource.FromVisual(this);
    var hwnd_target = hwnd_source.CompositionTarget;
    hwnd_target.RenderMode = System.Windows.Interop.RenderMode.SoftwareOnly;
}

弹出窗口在主窗口中心

//弹出
RuleSetting ruleWin = new RuleSetting();
ruleWin.SelectOneRule(listRuleInfo[index], index);
ruleWin.ShowDialog();
//初始化位置
public RuleSetting()
{
    InitializeComponent();
    MainWindow mainWindow = (MainWindow)Application.Current.MainWindow;
    this.Top =  mainWindow.Top + (mainWindow.Height - Height) / 2 ;
    this.Left = mainWindow.Left + (mainWindow.Width - Width) / 2;
}

设置FlowDocument页面的内容边界大小

通过设置PagePadding来实现

PagePadding=15
PagePadding=5

<FlowDocumentScrollViewer Grid.Row="1">
    <FlowDocument x:Name="tbConsole" Background="#FFC2C2C2" PagePadding="5">
    </FlowDocument>
</FlowDocumentScrollViewer>

给List添加弹出菜单

如果是Listview就改成ListView.ContextMenu

<ListBox Grid.Row="0" x:Name="lbServers"  d:ItemsSource="{d:SampleData ItemCount=5}" SelectionChanged="lbServers_Selected">
    <ListBox.ContextMenu>
        <ContextMenu>
            <MenuItem Name="MenuItemRuleDel" Header="删除选中"  Click="OnRuleMenuClick"/>
            <MenuItem Name="MenuItemRuleDelAll" Header="删除所有"  Click="OnRuleMenuClick"/>
        </ContextMenu>
    </ListBox.ContextMenu>
</ListBox>
//右键菜单点击
private void OnRuleMenuClick(object sender, RoutedEventArgs e)
{
    string menuname = ((MenuItem)sender).Name;
    int index = lbServers.SelectedIndex;

    switch (menuname)
    {
        case "MenuItemRuleDel":
            if (index == -1)
                return;
            DeleteRule(index);
            break;
        case "MenuItemRuleDelAll":
            if (index == -1)
                return;
            ReadyEditRule(index);
            break;
    }
}

添加状态栏

<DockPanel Grid.Row="2">
    <StatusBar DockPanel.Dock="Bottom">
        <StatusBarItem>
            <TextBlock Name="tbStat" Text="xxxxxx" />
        </StatusBarItem>
    </StatusBar>
</DockPanel>

Image更换内部图片

在xaml中直接可以通过source来显示:

<Image x:Name="imgNetstat"  Source="/pic/wifi_0.png"/>

后台脚本可以:

imgNetstat.Source = new BitmapImage(new Uri("pack://application:,,,/pic/wifi_1.png"));

这里要把图片属性里的生成操作改为资源(Resource),如下图:
在这里插入图片描述

子线程访问主线程里的组件

子线程调用主线程组件imgNetstat的更换图片

void OnConnetClose()
{
    imgNetstat.Dispatcher.Invoke(new Action(() => {
        imgNetstat.Source = new BitmapImage(new Uri("pack://application:,,,/pic/wifi_2.png"));
    }));
}

Label多重绑定

<Label>
    <TextBlock>
        <TextBlock.Text>
            <MultiBinding StringFormat="{}{0}({1})">
                <Binding Path="scenename"/>
                <Binding Path="passtime"/>
            </MultiBinding>
        </TextBlock.Text>
    </TextBlock>
</Label>

设置图片的高度是另外一个组件的高度

可以直接输入

Height="{Binding ElementName=printCanvas ,Path=Height}"

完整的如下:

<Canvas x:Name="printCanvas" Width="268" Height="30" HorizontalAlignment="Left" VerticalAlignment="Top">
    <Image x:Name="imgQR2"  Source="1.png" Stretch="UniformToFill" Height="{Binding ElementName=printCanvas ,Path=Height}"></Image>
   
</Canvas>

打印Canvas

<DockPanel Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Top">
    <!--<Button x:Name="btntest" Width="90" Height="90" Focusable ="False"  Click="testClick" FontSize="24"  >test</Button>-->
    
    <Canvas x:Name="printCanvas" Width="265" Height="190" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="3" Visibility="Hidden" >
        <DockPanel Canvas.Left="3" >
            <Border BorderBrush="#ff6600" BorderThickness="2" Margin="5">
                <Image x:Name="imgQR" Stretch="UniformToFill" Height="65" MouseDown="imgQR_MouseDown"></Image>
            </Border>
            <Grid Height="{Binding ElementName=printCanvas ,Path=Height}" >
                <Grid.RowDefinitions>
                    <RowDefinition Height="55"></RowDefinition>
                    <RowDefinition Height="25"></RowDefinition>
                </Grid.RowDefinitions>
                <Label Grid.Row="0" x:Name="tbPrintName" FontSize="26" VerticalContentAlignment="Top">TEST测试</Label>
                <Label Grid.Row="1" Canvas.Top="10" FontSize="12" VerticalContentAlignment="Center">你的名字</Label>
            </Grid>
            
        </DockPanel>
    </Canvas>
    
</DockPanel>

打印的代码

PrintDialog dlg = new PrintDialog();
dlg.PrintTicket.PageMediaSize = new PageMediaSize(70 / 25.4 * 96, 50 / 25.4 * 96); // 以英寸为单位设置
var sz = new Size(printCanvas.Width, printCanvas.Height);
printCanvas.Measure(sz);
var sz2 = sz;
sz2.Width = sz.Width +6;
sz2.Height = sz.Height + 6;
printCanvas.Arrange(new Rect(new System.Windows.Point(6, 6), sz2));

dlg.PrintVisual(printCanvas, "打印 - " + tbPrintName.Content);

Canvas的大小是265x190,是因为我的标签打印机纸张是70mm*50的。
需要根据dpi换算成像素 ,
将 毫米 转换为 英寸:
70mm÷25.4mm/inch=2.7559inch

将 英寸 转换为 像素(假设分辨率为 96 DPI):
2.7559inch×96px/inch=264px

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Thinbug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值