在编写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来实现
<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