目录
1. 将combox的selectionchanged事件和command绑定
2. 数据绑定, 实现INotifyPropertyChanged接口
5. WPF不能使用Console.WriteLine(msg)输出信息到控制台
8. 动态设置属性的Browsable特性,达到属性的显示和隐藏效果
11. wpf -- DataTemplate中Button的Command不生效
1. 将combox的selectionchanged事件和command绑定
View层:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
<ComboBox x:Name="comboBox1" Height="23" Width="120" SelectedValuePath="StuId" DisplayMemberPath="StuName" ItemsSource="{Binding StudentList}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding SelectItemChangedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
ViewModel层:
public ICommand SelectItemChangedCommand { get; set; }
构造函数中
SelectItemChangedCommand = new ActionCommand(this.NotifySelectedItemChanged);
事件:
public void NotifySelectedItemChanged()
{
MessageBox.Show("Sucess");
}
2. 数据绑定, 实现INotifyPropertyChanged接口
class ClassAViewModel:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string info)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info));
}
}
3. 使用值转换器为元素的Visibility属性绑定数据
创建值转换器:1.创建一个实现了IValueConverter接口的类
2. 为该类生命添加ValueConversion特性,并制定目标数据类型
3. 实现Convert()方法,该方法将数据从原来的格式转换为显示格式
4. 实现ConvertBack()方法,该方法执行反响变换,将值从显示格式转换为原格式
eg:
创建值转换器
[ValueConversion(typeof(bool),typeof(Visibility))]
public class VisibilityConvert : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool bl = (bool)value;
if (bl==true)
{
return Visibility.Visible;
}
else
{
return Visibility.Collapsed;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
定义属性,设置WholeMaterielVisibility的值为true或者false,即可改变元素的Visibility属性
private bool _wholeMaterielVisibility;
public bool WholeMaterielVisibility
{
get { return _wholeMaterielVisibility; }
set
{
if (_wholeMaterielVisibility != value)
{
_wholeMaterielVisibility = value;
NotifyPropertyChanged(nameof(WholeMaterielVisibility));
}
}
}
xaml,绑定:
<Window.Resources>
<local:VisibilityConvert x:Key="VisibilityConvert"></local:VisibilityConvert>
</Window.Resources>
Visibility="{Binding Path=WholeMaterielVisibility, Converter={StaticResource VisibilityConvert}}"
4. VS2019智能提示改为中文
① .netframework
将 v4.X 文件夹里的 zh-Hans 文件夹复制到你需要的版本文件夹里,重启VS即可
② .netcore
官网下载语言包,将语言包中与图1对应的文件夹里的zh-Hans文件进行复制或替换,如图2的位置,重启VS即可
图1
图2
5. WPF不能使用Console.WriteLine(msg)输出信息到控制台
故此采用以下方案:
using System.Diagnostics;
Debug.WriteLine(msg);
Trace.WriteLine(msg);
6. WPF的Image图片不显示
WPF的Image图片在界面编辑时是可以显示,但是在运行的时候却显示不出来
经过检查图片资源文件,发现是图片生成方式不对,图片右键 属性->生成操作改为Resource(资源)。生成操作设置为Resource,生成的时候资源将添加到程序集中。再重新生成项目,运行即可。
7. PropertyGrid的使用
nuget下载extended wpf toolkit,xaml调用
xmlns:extoolkit="http://schemas.xceed.com/wpf/xaml/toolkit"
<extoolkit:PropertyGrid SelectedObject="{Binding Pro}" Name="PropertyGrid1" Margin="0,45,-0.333,-0.333"></extoolkit:PropertyGrid>
cs调用
public class TestPropertyGrid
{
[Category("MyProperty")]
public int MyProperty { get; set; }
[Category("PropertyB")]
public string PropertyB { get; set; }
}
private TestPropertyGrid _pro;
public TestPropertyGrid Pro
{
get => _pro;
set => SetProperty(ref _pro, value);
}
UI
8. 动态设置属性的Browsable特性,达到属性的显示和隐藏效果
在使用PropertyGrid时,基于某些需求,需要动态显示/隐藏属性,本质是通过特性[Browsable(true)]来实现。调用以下方法可动态实现修改,使用此方法时,属性必须先用特性进行标记
/// <summary>
/// 设置属性的Browsable特性,达到属性的显示和隐藏效果
/// </summary>
/// <param name="obj">对象</param>
/// <param name="propertyName">属性名称</param>
/// <param name="visible">true:显示 false:隐藏</param>
public void SetPropertyVisibility(object obj, string propertyName, bool visible)
{
//反射实现对属性的特性复制
Type type = typeof(BrowsableAttribute);
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj);
AttributeCollection attrs = props[propertyName].Attributes;
FieldInfo fld = type.GetField("browsable", BindingFlags.Instance | BindingFlags.NonPublic);
fld.SetValue(attrs[type], visible);
}
9. DataGrid文本居中显示
①. 添加样式
<Style x:Key="CenterElementStyle" TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
②. 为ElementStyle绑定样式
<DataGrid ItemsSource="{Binding RecipeView}" SelectedItem="{Binding SelectRecipe}" >
<DataGrid.Columns>
<DataGridTextColumn Header="序号" Binding="{Binding Key}" Width="30" IsReadOnly="True" ElementStyle="{StaticResource CenterElementStyle}" />
</DataGrid.Columns>
</DataGrid>
10. wpf 记录按钮点击操作日志
在主view对应的cs文件下,添加按钮的路由事件处理程序
public MainView()
{
InitializeComponent();
//添加路由程序
EventManager.RegisterClassHandler(typeof(Button), ButtonBase.ClickEvent,
new RoutedEventHandler(OnClick));
}
private void OnClick(object sender, RoutedEventArgs e)
{
try
{
string buttonName;
string parentName;
Button button = sender as Button;
buttonName = button.Content?.ToString();
object obj = button?.DataContext;
//获取object(未知类型)的属性(包含Name)的值
PropertyInfo[] propertyInfo = obj?.GetType().GetProperties();
parentName = propertyInfo?.Where(x => x.Name.Contains("Name") && x.GetValue(obj) != null)?.Select(x => x.GetValue(obj).ToString())?.FirstOrDefault();
//没有name属性的处理
if (parentName==null)
{
parentName = obj?.ToString();
}
//使用log4net记录日志
LogHelper.TraceIn("","",$"用户触发了按钮->{buttonName},所属模块->{parentName}");
}
catch
{
}
}
日志输出:
2022-02-15 17:18:55,246:INFO - 用户触发了按钮->初始化,所属模块->窗体1
2022-02-15 17:18:57,760:INFO - 用户触发了按钮->开始流程,所属模块->窗体2
11. wpf -- DataTemplate中Button的Command不生效
原因:DataTemplate的DataContext指代不明确,需要改为父类的DataContext。
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
<xctk:PropertyGrid SelectedObject="{Binding VisionRecipeModel}" Margin="10" ShowAdvancedOptions="True" ShowDescriptionByTooltip="True" NameColumnWidth="270" >
<!-- PropertyGrid 自定义编辑模板 -->
<xctk:PropertyGrid.EditorDefinitions>
<xctk:EditorTemplateDefinition TargetProperties="LineOptions">
<xctk:EditorTemplateDefinition.EditingTemplate>
<DataTemplate>
<Grid>
<ToggleButton Height="25" x:Name="togLine" Content="点击"
<!-- 模板里的Command要做处理 RelativeSource 指向父类 传递的参数即 Value-->
Command="{Binding Path=DataContext.LineDetectCfgListSetCommand,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=xctk:PropertyGrid}}"
CommandParameter="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
</ToggleButton>
</Grid>
</DataTemplate>
</xctk:EditorTemplateDefinition.EditingTemplate>
</xctk:EditorTemplateDefinition>
</xctk:PropertyGrid.EditorDefinitions>
</xctk:PropertyGrid >