WPF日报

2022/1/4

1. 静态图标

将Image嵌入原控件

<Button>
         <Image Source="Resources\help.png"/>
</Button>

在模板中加多一个Image控件并指定永久性Source

<Image x:Name="img" Source="Resources\feedbackclose.png"/>

2. 动态图标

在模板中添加Image控件,通过Source设定原始图标
删除原来的IsMouseOver触发器 和 IsPressed触发器
添加Triggers,Proproty=“IsMouseOver”,Value=“True”,重置Image的Source
添加Triggers,Proproty=“IsPressed”,Value=“True”,重置Image的Source

       <Trigger Property="IsMouseOver" Value="True">
           <Setter TargetName="img" Property="Source" Value="Resources\morehover.png"/>
       </Trigger>
       <Trigger Property="IsPressed" Value="True">
           <Setter TargetName="img" Property="Source" Value="Resources\morepush.png"/>
       </Trigger>

3. 弹窗Popup

Popup,
PlacementTarget用于绑定弹在哪个元素,
Placement用于决定绑定在元素的哪个位置,
PlacementStaysOpen用于决定失焦后是否保持可见,
Closed事件发生在IsOpen为false时,

<Popup x:Name="p" 
	PlacementTarget="{Binding ElementName=b}"
	Placement="Bottom" 
	StaysOpen="False" 
	Closed="p_Closed" >

4. 文本框提示

Border,
Height为边框高度,
Width为边框宽度,
BorderBrush为边框颜色,
BorderThickness为边框大小,

VisualBrush,
Visutal为放入笔刷的内容,
AlignmentX为笔刷从哪里横坐标开始画,
AlignmentY为笔刷从哪里纵坐标开始画,
Stretch为笔刷内容是否按某种方式拉伸,

TextBox,
Height为边框高度,
Width为边框宽度,
BorderBrush为边框颜色,
BorderThickness为边框粗度,
TextWrapping为内容是否自动换行,

为Textbox添加样式触发器,当Text的Value为空时则使用自定义背景画刷,
另外,删除Textbox模板的触发器IsMouseOver和IsKeyboardFocused

<Border Height="200" Width="200" BorderBrush="black" BorderThickness="1">
    <TextBox Template="{DynamicResource TextBoxTemplate1}" Height="200" Width="200" BorderBrush="Transparent" BorderThickness="5" TextWrapping="Wrap">
        <TextBox.Resources>
            <VisualBrush x:Key="backbrush" AlignmentX="Left" AlignmentY="Top" Stretch="None">
                <VisualBrush.Visual>
                    <TextBlock Text="请输入名称"/>
                </VisualBrush.Visual>
            </VisualBrush>
        </TextBox.Resources>
        <TextBox.Style>
            <Style TargetType="TextBox">
                <Style.Triggers>
                    <Trigger Property="Text" Value="">
                        <Setter Property="Background" Value="{StaticResource backbrush}"/>
                    </Trigger>
                    <Trigger Property="Text" Value="{x:Null}">
                        <Setter Property="Background" Value="{StaticResource backbrush}"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </TextBox.Style>
    </TextBox>
</Border>

2022/1/5

1. 学习MVVM示例

2. 样式与控件模板

样式用于定义控件的外形以及属于空间的一些属性触发器,
模板用于一定控件的内容以及内容之间的一些触发器,
样式声明内可包含模板,样式与模板也可以单独声明,

单独Style

<Style x:Key="buttonstyle1" TargetType="Button">
    <Setter Property="Background" Value="Pink"/>
    <Setter Property="FontSize" Value="20"/>
    <Setter Property="Content" Value="content"/>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Content"  Value="555"/>
        </Trigger>
    </Style.Triggers>
</Style>

单独ControlTemplate

<ControlTemplate x:Key="buttontemplate1" TargetType="Button">
    <Border x:Name="border">
        <Image x:Name="img" Source="Resources\feedbackclosehover.png" Height="40" Width="40" />
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter TargetName="border" Property="Background" Value="Green"/>
        </Trigger>
        <Trigger Property="IsPressed" Value="True">
            <Setter TargetName="border" Property="Background" Value="Yellow"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

Style中声明ControlTemplate

<Style x:Key="buttonstyle1" TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Border x:Name="border">
                    <Image x:Name="img" Source="Resources\feedbackclosehover.png" Height="40" Width="40" />
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="border" Property="Background" Value="Green"/>
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter TargetName="border" Property="Background" Value="Yellow"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

3. 数据模板

CellTemplate(自定义模板为表格内容)

 <DataGrid x:Name="gd" AutoGenerateColumns="False" CanUserSortColumns="True"  CanUserAddRows="False">
     <DataGrid.Columns>
         <DataGridTextColumn Binding="{Binding UserName}" Width="100" Header="学生姓名"/>
         <DataGridTextColumn Binding="{Binding ClassName}" Width="100" Header="班级名称"/>
         <DataGridTextColumn Binding="{Binding Address}" Width="200" Header="地址"/>
         <DataGridTemplateColumn Header="操作" Width="100" >
             <DataGridTemplateColumn.CellTemplate>
                 <DataTemplate>
                     <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left">
                         <Button Content="编辑"/>
                         <Button Margin="8 0 0 0" Content="删除" />
                     </StackPanel>
                 </DataTemplate>
             </DataGridTemplateColumn.CellTemplate>
         </DataGridTemplateColumn>
     </DataGrid.Columns>
 </DataGrid>

ItemTemplate(自定义模板为控件项内容)

<Window.Resources>
    <DataTemplate x:Key="comTemplate">
        <StackPanel Orientation="Horizontal" Margin="5,0">
            <Border Width="10" Height="10" Background="{Binding Code}"/>
            <TextBlock Text="{Binding Code}" Margin="5,0"/>
        </StackPanel>
    </DataTemplate>
</Window.Resources>
<Grid>
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
        <ComboBox Name="cob" Width="120" Height="30" ItemTemplate="{StaticResource comTemplate}"/>
        <ListBox Name="lib" Width="120" Height="100" Margin="5,0"  ItemTemplate="{StaticResource comTemplate}"/>
    </StackPanel>
</Grid>

ItemsControl(利用数据生成相应的控件)

<ItemsControl Name="ic">
	 <ItemsControl.ItemsPanel>
	     <ItemsPanelTemplate>
	         <WrapPanel Orientation="Horizontal"/>
	     </ItemsPanelTemplate>
	 </ItemsControl.ItemsPanel>
	
	 <ItemsControl.ItemTemplate>
	     <DataTemplate>
	         <Button Width="50" Height="50" Content="{Binding Code}"/>
	     </DataTemplate>
	 </ItemsControl.ItemTemplate>
</ItemsControl>

2022/1/6

1. 编写WPF入门笔记

2. 学习 MVVM实例

3. 自编写MVVM实例

.xaml

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="20"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
            <Button Command="{Binding UpdateCommand}" Content="刷新"/>
            <TextBlock Text="班级名称:" Margin="10,0,0,0"/>
            <TextBlock Text="{Binding ClassName}"/>
        </StackPanel>
        <DataGrid Grid.Row="1" ItemsSource="{Binding Students}" AutoGenerateColumns="False" CanUserAddRows="False" ColumnWidth="*">
            <DataGrid.InputBindings>
                <MouseBinding MouseAction="LeftDoubleClick"
                           CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid},Path=SelectedItem}"
                           Command="{Binding ShowCommand}"/>
            </DataGrid.InputBindings>
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Name}" Header="名称"/>
                <DataGridTextColumn Binding="{Binding Age}"  Header="年龄"/>
                <DataGridTextColumn Binding="{Binding Sex}" Header="性别"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>

.xaml.cs

this.DataContext = new ViewModel.MainViewModel();

MainViewMedol.cs

public class MainViewModel : ViewModelBase
   {
       public MainViewModel()
       {
           //数据初始化
           ClassName = "高二三班";
           Students = new ObservableCollection<Student>();
           Students.Add(new Student() { Name = "张三", Age = 28, Sex = "男" });
           Students.Add(new Student() { Name = "李四", Age = 26, Sex = "女" });
           //命令声明
           ShowCommand = new RelayCommand<Student>(Show);
           UpdateCommand = new RelayCommand(Update);
       }
	   //班级名称
       private string className;
       public string ClassName
       {
           get { return className; }
           set { className = value;RaisePropertyChanged(); }
       }
	  //表格数据
       private ObservableCollection<Student> students;
       public ObservableCollection<Student> Students
       {
           get { return students; }
           set { students = value; RaisePropertyChanged(); }
       }
	   //show 命令
       public RelayCommand<Student> ShowCommand { get; set; }
       public void Show(Student stu)
       {
           MessageBox.Show($"Name:{stu.Name} Age:{stu.Age} Sex:{stu.Sex}");
       }

	   //update classname 命令
       public RelayCommand UpdateCommand { get; set; }
       public void Update()
       {
           ClassName = "高三三班";
       }
   }

Student.cs

 public class Student
 {
     private string name;

     public string Name
     {
         get { return name; }
         set { name = value; }
     }
     private int age;

     public int Age
     {
         get { return age; }
         set { age = value; }
     }

     private string sex;

     public string Sex
     {
         get { return sex; }
         set { sex = value; }
     }
 }

DB文件,用于程序有初始化数据时创建
Models文件,对事物进行抽象,并设计相关的函数
ViewModel文件,通过调用类对象的函数来实现对应的命令
View文件,通过Binding将ViiewModel的数据与命令进行绑定,实现双向通知

2022/1/7

1. 剖析RelayCommand类和RaisePropertyChanged()

自定义MyCommand

MyCommand类,
    public class MyCommand : ICommand
    {
        Action executeAction;
        public MyCommand(Action action)
        {
            executeAction = action;
        }
        public event EventHandler CanExecuteChanged;//命令状态发送变化时触发

        public bool CanExecute(object parameter)//判断是否可以执行
        {
            return true;
        }

        public void Execute(object parameter)//执行代码
        {
            executeAction();
        }
    }
VM代码,
    public class MainViewModel
    {
        
        public MainViewModel()
        {
            ShowCommand=new MyCommand(Show);
        }
        public MyCommand ShowCommand { get; set; }
        public void Show()
        {
            MessageBox.Show("点击了按钮");
        }
    }

VM自继承INotifyPropertyChanged

VM代码,
    public class MainViewModel : INotifyPropertyChanged
    {
        public MainViewModel()
        {
            ShowCommand=new MyCommand(Show);
        }
        public MyCommand ShowCommand { get; set; }
        public void Show()
        {
            Name = "new name do you like?";
        }
        
		public event PropertyChangedEventHandler PropertyChanged;
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name")); }
        }   
    }
    
为了减轻代码量 可实现VMBase,
    public class VMBase:INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged([CallerMemberName]String propertyName="")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

2. 文件的创建写入与打开读取

文件写入

FileStream fs=new FileStream(@"D:\Vs code\WpfApp3\save.txt", FileMode.OpenOrCreate,FileAccess.Write);
StreamWriter sw=new StreamWriter(fs);
sw.Flush();
sw.BaseStream.Seek(0, SeekOrigin.Begin);
sw.Write(res);
sw.Flush();
sw.Close();

文件读出

FileStream fs = new FileStream(@"D:\Vs code\WpfApp3\save.txt", FileMode.OpenOrCreate, FileAccess.Read);
StreamReader sr = new StreamReader(fs);
sr.BaseStream.Seek(0, SeekOrigin.Begin);
string res = sr.ReadLine();
sr.Close();

3. 学习SVN

2022/1/10

阅读工程代码

2022/1/11

1. Messenger类

引用类库,
using GalaSoft.MvvmLight.Messaging;

注册收件人,
Messenger.Default.Register<string>(this, "token1", Show);

发送信息给收件人,
Messenger.Default.Send(name, "token1");

2. MVVM的扩展工具包

在这里插入图片描述

3. 静态资源与动态资源的区别

本质:动态资源会根据资源的改变而实时改变,但是静态资源不会

.xaml
    <Window.Resources>
        <SolidColorBrush x:Key="solidbrush" Color="Pink"/>
    </Window.Resources>
    <StackPanel>
        <Button Content="Update" Click="Button_Click" Margin="10"/>
        <Button Content="Button1" BorderBrush="{StaticResource solidbrush}" BorderThickness="10" Margin="10"/>
        <Button Content="Button2" BorderBrush="{DynamicResource solidbrush}" BorderThickness="10" Margin="10"/>
    </StackPanel>

.cs
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        this.Resources["solidbrush"]=new SolidColorBrush(Colors.Green);
    }

4. 资源字典

目的:为使多个窗口使用相同的资源

添加ResourceDictionary Buttonstyle.xaml,
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <SolidColorBrush x:Key="solidbrush" Color="Pink"/>
</ResourceDictionary>

App.xaml并入资源字典,
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Buttonstyle.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

cs使用以下代码查找资源,
var solidbrush = App.Current.FindResource("solidbrush");

5. 动画

双精度动画,
private void btn_Click(object sender, RoutedEventArgs e)
{
    DoubleAnimation animation = new DoubleAnimation();  //创建一个双精度动画
    animation.From = btn.Width;                         //动画初始值
    animation.To = btn.Width - 30;                      //动画最终值
    //animation.By=-30;									//代替初始值与最终值
    animation.Duration = TimeSpan.FromSeconds(2);       //动画持续时长
    animation.AutoReverse = true;                       //动画是否还原
    animation.RepeatBehavior = RepeatBehavior.Forever;  //动画动作是否反复
    //animation.RepeatBehavior = new RepeatBehavior(3)
    animation.Completed+=Animation_Completed;			//添加动画完成函数
    btn.BeginAnimation(Button.WidthProperty, animation);
}
private void Animation_Completed(object sender, EventArgs e)
{	
	btn.Content="动画已完成";
}

6. Prism框架×

在这里插入图片描述

7. 网易云界面教程

1)可以借助矢量图标库特殊符号完成界面设计
2)注意Grid用于块整体设计
3)借助截图工具与取色器进行界面模仿

2022/1/12

对项目按照MVVM分层看,了解清楚FX的每个功能,熟悉客户端的功能模块

2022/1/13

1. WebSocket与HTTP的关系

WebSocket使用HTTP进行一次握手,然后走自己的协议,使用HTTP建立的那条TCP连接

2. WebSocket与Socket的区别

WebSocket区分服务器与客服端,Socket不区分
WebSocket实现了服务器的主动信息推送
WebSocket是一种应用层的协议,而Socket只是对TCP/UDP作封装

3. 基于SignalR的网络聊天室

2022/1/14

1. 进程通信

2. 线程的创建与通信

线程的同步与异步,
Action<int, int> add = (int x, int y) =>	//定义一个方法
{
    MessageBox.Show((x + y).ToString());
};
add.Invoke(5,6);                //该Action在当前线程同步运行
add.BeginInvoke(7, 8,null,null);//该Action另外创线程异步运行
}

3. VS在指定文件快速查找变量 Ctrl+F

4. Action与Func(对委托的一种泛型封装)

Func有返回值,最多包含16个泛型参数,加一个返回值
Action无返回值,最多包含16个泛型参数

匿名函数,
Func<int, int, int> add1 = delegate (int x, int y)
{
    return x + y;
};
Action<int, int> add2 = delegate (int x, int y)
{
    MessageBox.Show((x + y).ToString());
};

Lamada表达式,
Func<int, int, int> add1 = (int x, int y)=>
{
    return x + y;
};
Action<int, int> add2 = (int x, int y) =>
{
    MessageBox.Show((x + y).ToString());
};	

5. 异步线程结束后的回调函数AsyncCallback

Action<int, int> add = (int x, int y) =>
{
    MessageBox.Show((x + y).ToString());
};
AsyncCallback callback = arg =>
{
    MessageBox.Show(arg.AsyncState.ToString());
    MessageBox.Show("异步线程已结束");
};
add.BeginInvoke(7, 8, callback, "Sunday");

//函数的参数意义
BeginInvoke(
T args,
AsynCallback callback,
Object object
}

6. 观察异步线程的执行状况

IAsyncResult asyncResult=action.BeginInvoke("文件上传",null,null);
while(!asyncResult.IsCompleted)
{
    label.Content="文件还在上传...";
}
label.Content = "文件已经上传";

7. 阻塞当前线程进行等待

IAsyncResult asyncResult=action.BeginInvoke("文件上传",null,null);
asyncResult.AsyncWaitHandle.WaitOne();//阻塞当前线程,直到异步线程结束
asyncResult.AsyncWaitHandle.WaitOne(-1);//永远阻塞,直到异步线程结束
asyncResult.AsyncWaitHandle.WaitOne(1000);//阻塞1000ms
MessageBox.Show("文件上传完成");

8. 获取线程的返回值

//同步线程返回值的获取办法
int res1 = func();
int res2 = func.Invoke();
//异步线程返回值的获取办法
IAsyncResult asyncResult = func.BeginInvoke(null, null);
int res3=func.EndInvoke(asyncResult);

2022/1//17

1. Thread类

//.NetFramework 1.0 1.1
ThreadStart threadstart = () =>
{
    Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}:Start");
    Thread.Sleep(2000);
    Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}:End");
};
Thread thread = new Thread(threadstart);
thread.Start();
 
Thread的优点,
1. API极其丰富,可以很彻底地让操作系统操控线程
Thread的缺点,
2. 线程资源是操作系统的,对其过度干扰可能会造成死机

2. ThreadPool类

//.NetFramework 2.0 (新的CLR Common language Runtime)
WaitCallback callback = o =>
 {
     Console.WriteLine($"This {Thread.CurrentThread.ManagedThreadId} ThreadPoll:Start");
     Thread.Sleep(2000);
     Console.WriteLine($"This {Thread.CurrentThread.ManagedThreadId} ThreadPoll:End");
 };
ThreadPool.QueueUserWorkItem(callback);

ThreadPool的特点,
主线程等待
ThreadPool的优点,
池化管理线程资源,实现自主地线程申请与释放,减少线程频繁创建销毁的次数
ThreadPool的缺点,
提供太少的API,就线程的执行顺序控制十分不方便

3. Parallel类

//.NetFramework 2.0
Console.WriteLine($"This {Thread.CurrentThread.ManagedThreadId} MainThread:Start");
Parallel.Invoke(() =>
{
   Console.WriteLine($"This {Thread.CurrentThread.ManagedThreadId} Parallel:Start1");
   Thread.Sleep(2000);
   Console.WriteLine($"This {Thread.CurrentThread.ManagedThreadId} Parallel:End1");
},
() =>
{
   Console.WriteLine($"This {Thread.CurrentThread.ManagedThreadId} Parallel:Start2");
   Thread.Sleep(2000);
   Console.WriteLine($"This {Thread.CurrentThread.ManagedThreadId} Parallel:End2");
},
() =>
{
   Console.WriteLine($"This {Thread.CurrentThread.ManagedThreadId} Parallel:Start3");
   Thread.Sleep(2000);
   Console.WriteLine($"This {Thread.CurrentThread.ManagedThreadId} Parallel:End3");
}
);
Console.WriteLine($"This {Thread.CurrentThread.ManagedThreadId} MainThread:End");


Parallel的特点,
主线程等待
Parallel的优点,
1. 产生多线程后,主线程不闲置而是一起干活
2. 可以通过ParallelOptions轻松控制最大并发线程数
3. 线程全部由线程池生成

4. Task类

//.NetFramework 3.0
Action action = () =>
{
    Console.WriteLine($"This {Thread.CurrentThread.ManagedThreadId} Parallel:Start1");
    Thread.Sleep(2000);
    Console.WriteLine($"This {Thread.CurrentThread.ManagedThreadId} Parallel:End1");
};
Task task=new Task(action);
task.Start();

Task的特点,
主线程不等待
Task的优点,
1. 线程全部由线程池生成
2. 提供了丰富的API

5. Task类等待指定的线程数组(即保证顺序性)

List<Task> tasks = new List<Task>();
tasks.Add(Task.Run(() => this.Coding("111", "111")));
tasks.Add(Task.Run(() => this.Coding("222", "222")));
tasks.Add(Task.Run(() => this.Coding("333", "333")));
tasks.Add(Task.Run(() => this.Coding("444", "444")));
Task.WaitAll(tasks.ToArray());//阻塞主线程直到所有任务完成
Task.WaitAll(tasks.ToArray());//阻塞主线程直到任意任务完成

缺点,
因为阻塞主线程,所以会有卡界面的问题
解决1,
为当前等待任务再创一个线程,这样就不会卡界面了
但是,
尽量最好不要线程套线程,而让每个线程作为一个简单的工作单元
另外创建的等待线程如果想要更新主界面,还需要切换主线程
解决2,
使用TaskFactory类的ContinueWhenAll/ContinueWhenAny方法,
TaskFactory taskFactory = new TaskFactory();
taskFactory.ContinueWhenAll(tasks.ToArray(), tArray =>
{
    Console.WriteLine($"This {Thread.CurrentThread.ManagedThreadId} MainThread:End");
});

6. 循环创建线程的多线程安全问题

for(int i = 0; i < 5; i++)
{
    int k = i;
    Task.Run(() =>
    {
        Console.WriteLine($"This is{i} {k} Start...{Thread.CurrentThread.ManagedThreadId}");
    });
}  

输出结果
This is5 0 Start...3
This is5 3 Start...5
This is5 4 Start...5
This is5 1 Start...4
This is5 2 Start...3

1. 为什么全是5?
主线程作i++的操作,匿名函数作输出操作,由于主线程执行的太快,导致i全是5
2. 为什么k是0 1 2 3 4?
因为实际上主线程有5个k,5个k分别被5个线程打印,它们互不干扰,所以能正确输出

7. 解决线程安全问题Lock

List<int> intList = new List<int>();
for(int i = 0; i < 10000; i++)
{
    Task.Run(() =>
    {
        lock (LOCK)
        {
            intList.Add(i);
        }
    });
}
Thread.Sleep(5000);
Console.WriteLine(intList.Count);

private static readonly object LOCK = new object();

lock(LOCK)
等价于,
Monitor.Enter(LOCK);
Monitor.Exit(LOCK);

lock原理是锁定引用,即一块内存地址,不能锁定值类型或null

看完4-3

2022/1/18

查看倍速工程代码

2022/1/19

1. 倍速工程代码移动

2. 使用ItemControl

<Grid>
    <Button x:Name="btn" Width="100" Height="40" Click="btn_Click" Content="1.0x"/>
    <Popup x:Name="popup" Placement="Top" PlacementTarget="{Binding ElementName=btn}" StaysOpen="False">
        <StackPanel>
            <ItemsControl ItemsSource="{Binding Lists}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel  Width="100"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <RadioButton GroupName="speedgroup">
                            <RadioButton.Template>
                                <ControlTemplate>
                                    <Grid x:Name="grid" Background="Black">
                                        <TextBlock x:Name="block" Text="{Binding str1}" Foreground="White" HorizontalAlignment="Center"/>
                                    </Grid>
                                    <ControlTemplate.Triggers>
                                        <Trigger Property="RadioButton.IsMouseOver" Value="True">
                                            <Setter TargetName="grid" Property="Background" Value="Gray"/>
                                        </Trigger>
                                        <Trigger Property="RadioButton.IsPressed" Value="True">
                                            <Setter TargetName="block" Property="Foreground" Value="Orange"/>
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </RadioButton.Template>
                        </RadioButton>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </StackPanel>
    </Popup>
</Grid>

2022/1/23

1. 不要擅自修改JCE文件,而是去OA下载

jce文件去OA找到JCE管理中心,
下载对应的文件名对应的版本,
生成依赖,
然后解压找到自己需要在文件进行替换

2. 提交文件

Commit修改的文件夹,
将自己另外添加的文件使用Add,
在提交前通过SVN对比修改前后的代码

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FluentUI WPF是一个用于Windows Presentation Foundation(WPF)的开源UI库,它提供了一套高质量的UI组件和样式,用于构建具有专业外观和用户体验的应用程序。Fluent UI的名称来源于Microsoft Fluent Design System,这是微软公司推出的新一代设计语言,旨在提供一致、现代和直观的用户体验。 Fluent UI WPF提供了以下主要功能和特点: 1. 丰富的UI组件:Fluent UI WPF提供了各种常用的UI组件,如按钮、文本框、标签、列表、网格、布局容器等,以及自定义控件和工具提示等。 2. 美观的视觉效果:Fluent UI WPF具有高度定制的样式和外观,提供了多种主题和视觉效果,可以满足不同风格和场景的需求。 3. 可扩展性:Fluent UI WPF提供了丰富的自定义选项,可以根据具体需求定制组件的外观和行为,以满足个性化的需求。 4. 良好的性能:Fluent UI WPF在设计时注重性能优化,能够高效地渲染和响应用户操作,同时支持高性能的数据绑定和布局管理。 5. 跨平台支持:Fluent UI WPF不仅适用于Windows平台,还支持其他平台(如MacOS和Linux)上的WPF应用程序开发。 要使用Fluent UI WPF,您需要了解WPF的基础知识和设计原则,并具备一定的C#编程经验。您可以使用NuGet包管理器将Fluent UI WPF组件集成到您的项目中,并按照文档和示例进行配置和使用。Fluent UI WPF的文档和示例资源可以在开源代码库中找到。 需要注意的是,Fluent UI WPF是一个开源库,但并非所有功能都完全免费。某些高级功能可能需要购买商业许可才能使用。因此,在决定使用Fluent UI WPF之前,请务必仔细阅读相关文档和许可协议。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值