界面<UserControl x:Class="TEST.UserControls.UC_StationInfo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:converters="clr-namespace:TEST.Converters"
xmlns:local="clr-namespace:TEST.Themes"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
mc:Ignorable="d" d:DesignWidth="300" d:Height="60" MouseDoubleClick="Grid_MouseLeftButtonDown">
<UserControl.Resources>
<converters:CvtBool2Visibility x:Key="cvtBool2Visibility"/>
</UserControl.Resources>
<Grid Background="Transparent" Height="60" >
<Grid.ContextMenu>
<ContextMenu Style="{x:Null}">
<MenuItem Header="移除玻片" Click="DeleteGlass_Click" Margin="0,3"/>
</ContextMenu>
</Grid.ContextMenu>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Height="30" Width="30" Margin="5,5,5,5">
<Ellipse VerticalAlignment="Stretch" Stroke="Black" StrokeThickness="2" />
<Label HorizontalAlignment="Center" VerticalAlignment="Center" VerticalContentAlignment="Center" d:Content="10"
Content="{Binding Number, RelativeSource={RelativeSource AncestorType=UserControl},UpdateSourceTrigger=PropertyChanged}" FontSize="16" FontWeight="Bold"/>
</Grid>
<Grid Height="50" Width="150" Grid.Column="1">
<Border BorderBrush="Black" BorderThickness="1" CornerRadius="5" Background="#CCCCCC" Width="140" />
<Border BorderBrush="Black" BorderThickness="1" CornerRadius="5" Background="#D1FFF2" Width="140" Visibility="{Binding IsLoad, RelativeSource={RelativeSource AncestorType=UserControl},UpdateSourceTrigger=PropertyChanged, Converter={StaticResource cvtBool2Visibility}}"/>
<Line Stroke="Red" StrokeThickness="2" X1="50" Y1="10" X2="100" Y2="40" Visibility="{Binding IsError, RelativeSource={RelativeSource AncestorType=UserControl},UpdateSourceTrigger=PropertyChanged, Converter={StaticResource cvtBool2Visibility}}"/>
<Line Stroke="Red" StrokeThickness="2" X1="100" Y1="10" X2="50" Y2="40" Visibility="{Binding IsError, RelativeSource={RelativeSource AncestorType=UserControl},UpdateSourceTrigger=PropertyChanged, Converter={StaticResource cvtBool2Visibility}}"/>
<TextBlock VerticalAlignment="Top" Margin="10,3" FontSize="14"
d:Text="123456789" Text="{Binding GlassId, RelativeSource={RelativeSource AncestorType=UserControl},UpdateSourceTrigger=PropertyChanged}" />
<TextBlock VerticalAlignment="Bottom" Margin="10,3" FontSize="14"
d:Text="Desmin" Text="{Binding CategoryName, RelativeSource={RelativeSource AncestorType=UserControl},UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</Grid>
</UserControl>
后台/// <summary>
/// UC_StationInfo.xaml 的交互逻辑
/// </summary>
public partial class UC_StationInfo : UserControl
{
public UC_StationInfo()
{
InitializeComponent();
}
public event Action<int> RemoveGlassAction;
// 定义 IsError 依赖属性
public static readonly DependencyProperty IsErrorProperty = DependencyProperty.Register(nameof(IsError), typeof(bool), typeof(UC_StationInfo), new PropertyMetadata(false));
public bool IsError
{
get => (bool)GetValue(IsErrorProperty);
set => SetValue(IsErrorProperty, value);
}
// 定义 IsLoad 依赖属性
public static readonly DependencyProperty IsLoadProperty = DependencyProperty.Register(nameof(IsLoad), typeof(bool), typeof(UC_StationInfo), new PropertyMetadata(false));
public bool IsLoad
{
get => (bool)GetValue(IsLoadProperty);
set => SetValue(IsLoadProperty, value);
}
// 定义 CategoryName(标记名) 依赖属性
public static readonly DependencyProperty CategoryNameProperty = DependencyProperty.Register(nameof(CategoryName), typeof(string), typeof(UC_StationInfo), new PropertyMetadata(string.Empty));
public string CategoryName
{
get => (string)GetValue(CategoryNameProperty);
set => SetValue(CategoryNameProperty, value);
}
// 定义 Number(序号) 依赖属性
public static readonly DependencyProperty NumberProperty = DependencyProperty.Register(nameof(Number), typeof(int), typeof(UC_StationInfo), new PropertyMetadata(1));
public int Number
{
get => (int)GetValue(NumberProperty);
set => SetValue(NumberProperty, value);
}
// 依赖属性定义(
public static readonly DependencyProperty GlassIdProperty = DependencyProperty.Register(nameof(GlassId), typeof(string), typeof(UC_StationInfo), new PropertyMetadata(string.Empty));
public string GlassId
{
get => (string)GetValue(GlassIdProperty);
set
{
SetValue(GlassIdProperty, value);
IsLoad = value.Length > 5;
}
}
// 依赖属性定义(
#region 私有方法
/// <summary>
/// 统一处理添加逻辑
/// </summary>
private void HandleAddGlass()
{
if (GlassId.Length < 5)
return;
RemoveGlassAction?.Invoke(Number);
GlassId = CategoryName = "";
}
// 合并事件处理
private void DeleteGlass_Click(object sender, RoutedEventArgs e) => HandleAddGlass();
private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => HandleAddGlass();
#endregion
}
界面<UserControl x:Class="TEST.UserControls.UC_GlassInfo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:converters="clr-namespace:TEST.Converters"
xmlns:local="clr-namespace:TEST.Themes"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
mc:Ignorable="d" d:DesignWidth="160" d:Height="55" MouseDoubleClick="Grid_MouseLeftButtonDown">
<Grid Background="Transparent" Height="55" Visibility="{Binding IsShow ,RelativeSource={RelativeSource AncestorType=UserControl}, UpdateSourceTrigger=PropertyChanged,Converter={converters:CvtBool2Visibility UseHidden=False}}">
<Grid.ContextMenu >
<ContextMenu Style="{x:Null}">
<MenuItem Header="添加玻片" Click="AddGlass_Click" Margin="0,3"/>
</ContextMenu>
</Grid.ContextMenu>
<Grid Height="50" Width="150" Grid.Column="1">
<Border BorderBrush="Black" BorderThickness="1" CornerRadius="5" Background="#D1FFF2" Width="140" />
<TextBlock VerticalAlignment="Top" Margin="10,3" FontSize="14"
d:Text="123456789" Text="{Binding GlassId, RelativeSource={RelativeSource AncestorType=UserControl},UpdateSourceTrigger=PropertyChanged}" />
<TextBlock VerticalAlignment="Bottom" Margin="10,3" FontSize="14"
d:Text="Desmin" Text="{Binding CategoryName, RelativeSource={RelativeSource AncestorType=UserControl},UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</Grid>
</UserControl>后台 public partial class UC_GlassInfo : UserControl, INotifyPropertyChanged
{
public UC_GlassInfo()
{
InitializeComponent();
// 设置数据上下文为自身(支持绑定)
DataContext = this;
}
public event Action<KeyValuePair<string, string>> AddGlassAction;
// 定义 CategoryName(标记名) 依赖属性
public static readonly DependencyProperty CategoryNameProperty = DependencyProperty.Register(nameof(CategoryName), typeof(string), typeof(UC_GlassInfo), new PropertyMetadata(string.Empty));
public string CategoryName
{
get => (string)GetValue(CategoryNameProperty);
set => SetValue(CategoryNameProperty, value);
}
// 依赖属性定义(
public static readonly DependencyProperty GlassIdProperty = DependencyProperty.Register(nameof(GlassId), typeof(string), typeof(UC_GlassInfo), new PropertyMetadata(string.Empty));
public string GlassId
{
get => (string)GetValue(GlassIdProperty);
set => SetValue(GlassIdProperty, value);
}
// 依赖属性定义(
public static readonly DependencyProperty SampleIdProperty = DependencyProperty.Register(nameof(SampleId), typeof(string), typeof(UC_GlassInfo), new PropertyMetadata(string.Empty));
public string SampleId
{
get => (string)GetValue(SampleIdProperty);
set => SetValue(SampleIdProperty, value);
}
// 依赖属性定义(
public static readonly DependencyProperty IsLoadProperty = DependencyProperty.Register(nameof(IsLoad), typeof(bool), typeof(UC_GlassInfo), new PropertyMetadata(false));
public bool IsLoad
{
get => (bool)GetValue(IsLoadProperty);
set => SetValue(IsLoadProperty, value);
}
// 添加 IsShow 作为 CLR 属性(支持双向绑定)
private bool _isShow = true;
public bool IsShow
{
get => _isShow;
set
{
if (_isShow != value)
{
_isShow = value;
OnPropertyChanged(nameof(IsShow));
// 可选:自动更新可见性
//Visibility = value ? Visibility.Visible : Visibility.Collapsed;
}
}
}
// 实现 INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#region 私有方法
/// <summary>
/// 统一处理添加逻辑
/// </summary>
private void HandleAddGlass()
{
AddGlassAction?.Invoke(new KeyValuePair<string, string>(GlassId, CategoryName));
}
// 合并事件处理
private void AddGlass_Click(object sender, RoutedEventArgs e) => HandleAddGlass();
private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => HandleAddGlass();
#endregion
}
使用界面
<Window x:Class="TEST.UserControls.windows.Wd_GlassInfoAdd"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:themes="clr-namespace:TEST.Themes"
xmlns:converters="clr-namespace:TEST.Converters"
mc:Ignorable="d"
WindowStartupLocation="CenterScreen"
Style="{StaticResource BaseWindowStyle}"
Title="模块手动添加玻片" Height="800" Width="680" >
<Window.Resources>
<Style x:Key="ProductToggleStyle" TargetType="ToggleButton">
<Setter Property="Height" Value="35"/>
<Setter Property="MinWidth" Value="30"/>
<Setter Property="MaxWidth" Value="150"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border x:Name="border" Background="{TemplateBinding Background}" CornerRadius="5" Margin="5"
BorderThickness="1" BorderBrush="Black">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="3,0"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="border" Property="Background" Value="Green"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter TargetName="border" Property="Background" Value="White"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="Background" Value="{DynamicResource Accent}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<converters:Int2BoolConverter x:Key="cvtInt2Bool"/>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="230"/>
<ColumnDefinition Width="225"/>
<ColumnDefinition Width="220"/>
</Grid.ColumnDefinitions>
<Grid>
<Grid Width="32" Height="32" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="10">
<Ellipse Width="30" Height="30" VerticalAlignment="Stretch" Stroke="#4c4c4c" Fill="#4c4c4c"/>
<Label Padding="3" HorizontalAlignment="Center" d:Content="A" Content="{Binding ModuleName}" FontSize="20" FontWeight="Bold" Foreground="White"/>
</Grid>
<Border BorderThickness="2" BorderBrush="Black" CornerRadius="5" Margin="5,50,5,50" Background="White">
<ListBox Margin="-1" ItemsSource="{Binding GlassStationList}" SelectedIndex="{Binding GlassStationSelectedIndex}" Background="Transparent">
<ListBox.Style>
<Style TargetType="ListBox" >
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<!--<Setter Property="ScrollViewer.Padding" Value="0,0,17,0"/>-->
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ListBoxItem" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem" >
<Border Name="border" BorderBrush="{x:Null}" Background="{TemplateBinding Background}" BorderThickness="2" HorizontalAlignment="Left"
MaxWidth="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=ScrollViewer}, Converter={StaticResource cvtValuePlus},ConverterParameter=-20}">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#999999"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
</ListBox.Style>
</ListBox>
</Border>
</Grid>
<Grid Grid.Column="1">
<StackPanel Orientation="Vertical" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="0,10" IsEnabled="{Binding IsCanSeltctedItem}" Width="150">
<Label Content="筛选条件:" Width="90" FontSize="18" HorizontalAlignment="Left"/>
<RadioButton GroupName="Volume" Width="70" Margin="30,3"
Content="全部" IsChecked="{Binding FiltrateType, Converter={StaticResource cvtInt2Bool}, ConverterParameter=0}" />
<RadioButton GroupName="Volume" Width="70" Margin="30,3"
Content="标记" IsChecked="{Binding FiltrateType, Converter={StaticResource cvtInt2Bool}, ConverterParameter=1}" />
<RadioButton GroupName="Volume" Width="80" Margin="30,3"
Content="病例ID" IsChecked="{Binding FiltrateType, Converter={StaticResource cvtInt2Bool}, ConverterParameter=2}" />
</StackPanel>
<DataGrid Margin="5,120,5,50" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Hidden" CanUserSortColumns="False" SelectionMode="Single"
ItemsSource="{Binding FiltrateInfoList, Mode=OneWay}" SelectedItem="{Binding SelectedItem}" IsEnabled="{Binding IsCanSeltctedItem}">
<DataGrid.Columns >
<DataGridTextColumn Header="序号" Width="40" Binding="{Binding Sid}" />
<DataGridTextColumn d:Header="标记/病例ID" Width="100" Binding="{Binding ReagentName}">
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},Path=DataContext.FiltrateName}"/>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>
<!--<DataGridCheckBoxColumn Header="选择" Width="60" IsReadOnly="False" Binding="{Binding IsChoosed}"/>-->
<!--<DataGridTemplateColumn Width="50" Header="选择" SortMemberPath="IsChoosed">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=IsPrefrence,Mode=TwoWay}" Style="{StaticResource CheckBoxStyleBase}" Height="15" HorizontalAlignment="Center"
Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}, Path=DataContext.SetPrefrenceCommand}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>-->
</DataGrid.Columns>
</DataGrid>
</Grid>
<!--<Border Grid.Column="1" Height="350" Background="Honeydew" Margin="5" BorderBrush="Black" BorderThickness="1" CornerRadius="5">
<ScrollViewer Margin="2,10" VerticalScrollBarVisibility="Auto" Background="Transparent" HorizontalScrollBarVisibility="Disabled">
<ItemsControl x:Name="itemsControl" ItemsSource="{Binding FilteredCategoryList}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" ItemWidth="NaN" HorizontalAlignment="Left"
Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=ScrollViewer},Converter={StaticResource cvtValuePlus}, ConverterParameter=-16}"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ToggleButton Content="{Binding Name}" Style="{StaticResource ProductToggleStyle}" IsChecked="{Binding IsSelected, Mode=TwoWay}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Border>-->
<Grid Grid.Column="2">
<!--<Grid Margin="5,20" Height="120" VerticalAlignment="Top">
<Border BorderBrush="Black" Grid.RowSpan="2" BorderThickness="2" CornerRadius="10" Background="Black">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="预览" Margin="8,0" VerticalAlignment="Center" Foreground="White" FontSize="18"/>
<Border Background="#e7e7e7" Grid.Row="1" CornerRadius="0,0,10,10"/>
<Grid Grid.Row="1">
<themes:GlassPice DataContext="{Binding GlassPiece}" Width="180" Height="60" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</Grid>
</Border>
</Grid>-->
<Label Padding="3" HorizontalAlignment="Left" Content="玻片列表" FontSize="18" VerticalAlignment="Top" Margin="10"/>
<Border Margin="0,50" BorderBrush="Black" BorderThickness="2" CornerRadius="5">
<ListBox Margin="0" SelectedItem="{Binding SelectedGlassInfo}" ItemsSource="{Binding FiltrateGlassInfo}" Padding="0" ScrollViewer.CanContentScroll="False">
<ListBox.Style>
<Style TargetType="ListBox">
<Setter Property="ItemContainerStyle">
<Setter.Value >
<Style TargetType="ListBoxItem">
<Setter Property="Margin" Value="0,-2"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border Name="border" BorderBrush="{x:Null}" Background="{TemplateBinding Background}" BorderThickness="2" Height="{TemplateBinding Height}">
<ContentPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#999999"/>
</Trigger>
<Trigger Property="Visibility" Value="Collapsed">
<Setter TargetName="border" Property="Height" Value="0"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<!-- 3. 样式触发器(放在所有Setter之后) -->
<Style.Triggers>
<Trigger Property="Visibility" Value="Collapsed">
<Setter Property="Height" Value="0"/>
<Setter Property="Focusable" Value="False"/>
</Trigger>
</Style.Triggers>
</Style>
</Setter.Value>
</Setter>
</Style>
</ListBox.Style>
</ListBox>
</Border>
<StackPanel Height="40" VerticalAlignment="Bottom" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="确定" Margin="10,0" Click="ButtonOK_Click"/>
<Button Content="取消" Margin="10,0" Click="ButtonCancle_Click"/>
</StackPanel>
</Grid>
</Grid>
</Window>后台程序
public partial class Wd_GlassInfoAdd : Window
{
public Wd_GlassInfoAdd(int states, List<string> glsIdList)
{
InitializeComponent();
var model = new Wd_GlassInfoAddViewModel(states, glsIdList);
model.SelectedGlassListOverEvent += Model_SelectedGlassOverEventList;
DataContext = model;
for (int i = 0; i < GlobalVars.GlassCnt; i++)
{
GlassIdList.Add("");
}
}
public List<string> GlassIdList { get; set; } = new List<string>();
private void ButtonCancle_Click(object sender, RoutedEventArgs e)
{
DialogResult = false;
Close();
}
private void ButtonOK_Click(object sender, RoutedEventArgs e)
{
DialogResult = true;
Close();
}
private void Model_SelectedGlassOverEventList(List<string> obj)
{
GlassIdList = obj;
}
}
public class Wd_GlassInfoAddViewModel : ObservableObject
{
private GlassLabeInfoMode selectedItem;
private ObservableCollection<UC_GlassInfo> filtrateGlassInfo = new();
private ObservableCollection<GlassLabeInfoMode> filtrateInfoList = new();
private UC_GlassInfo selectedGlassInfo;
private int glassStationSelectedIndex = -1;
private int filtrateType = 0;
private string filtrateName = "全部";
private bool isCanSeltctedItem = true;
public Wd_GlassInfoAddViewModel(int states, List<string> glsIdList)
{
ModuleName = ((char)('A' + (char)(states >> 12))).ToString(); ;
LoadFormDB();
for (int i = 0; i < GlobalVars.GlassCnt; i++)
{
GlassStationList.Add(new UC_StationInfo { Number = i + 1, CategoryName = "", GlassId = "", IsError = (0x01 << i & states) > 0 });
GlassStationList[i].RemoveGlassAction += RemoveGlass;
if (glsIdList[i].Length > 5 && GlassStationList[i].IsError == false)//加载已经存在的玻片
{
var itemToRemove = FiltrateGlassInfo.FirstOrDefault(x => x.GlassId == (glsIdList[i]));
if (itemToRemove != null)
{
itemToRemove.IsLoad = true;
itemToRemove.IsShow = false;
GlassStationList[i].GlassId = itemToRemove.GlassId;
GlassStationList[i].CategoryName = itemToRemove.CategoryName;
}
}
}
}
/// <summary>
/// 返回玻片ID列表
/// </summary>
public event Action<List<string>> SelectedGlassListOverEvent;
/// <summary>
/// 模块名
/// </summary>
public string ModuleName { get; set; }
/// <summary>
/// 玻片位选择编号
/// </summary>
public int GlassStationSelectedIndex { get => glassStationSelectedIndex; set { glassStationSelectedIndex = value; OnPropertyChanged(); } }
///// <summary>
///// 所有玻片信息
///// </summary>
//public ObservableCollection<GlassLabeInfoMode> GlassInfoList { get; } = new ObservableCollection<GlassLabeInfoMode>();
/// <summary>
/// 10个玻片位加载玻片信息
/// </summary>
public ObservableCollection<UC_StationInfo> GlassStationList { get; } = new ObservableCollection<UC_StationInfo>();
public ObservableCollection<GlassLabeInfoMode> FiltrateInfoList { get => filtrateInfoList; set { SetProperty(ref filtrateInfoList, value); } }
public string FiltrateName { get => filtrateName; set { SetProperty(ref filtrateName, value); } }
public bool IsCanSeltctedItem { get => isCanSeltctedItem; set { SetProperty(ref isCanSeltctedItem, value); } }
public GlassLabeInfoMode SelectedItem
{
get => selectedItem;
set
{
if (SetProperty(ref selectedItem, value))
{
if (value == null || FiltrateName == "全部")
{
foreach (var item in FiltrateGlassInfo)
{
item.IsShow = !item.IsLoad;
}
}
else
{
if (FiltrateName == "标记")
{
foreach (var item in FiltrateGlassInfo)
{
if (item.CategoryName == value.ReagentName && item.IsLoad == false)
{
item.IsShow = true;
}
else
{
item.IsShow = false;
}
}
}
else
{
foreach (var item in FiltrateGlassInfo)
{
if (item.SampleId == value.ReagentName && item.IsLoad == false)
{
item.IsShow = true;
}
else
{
item.IsShow = false;
}
}
}
}
}
}
}
public int FiltrateType
{
get => filtrateType;
set
{
if (SetProperty(ref filtrateType, value))
{
IsCanSeltctedItem = false;
SelectedItem = null;
FiltrateInfoList = new ObservableCollection<GlassLabeInfoMode>();
if (value == 1)//选择标记筛选
{
FiltrateInfoList = new ObservableCollection<GlassLabeInfoMode>();
FiltrateName = "标记";
var catenameList = FiltrateGlassInfo.Where(x => x.IsLoad == false).Select(x => x.CategoryName).ToList()
.Where(s => !string.IsNullOrEmpty(s)).Distinct().ToList();// 去除空字符串 ,去除重复项。 转换为列表
int i = 1;
foreach (var g in catenameList)
{
FiltrateInfoList.Add(new GlassLabeInfoMode { Sid = i++, ReagentName = g });
}
}
else if (value == 2)//选择病例筛选
{
FiltrateName = "病例ID";
var smpList = FiltrateGlassInfo.Where(x => x.IsLoad == false).Select(x => x.SampleId).ToList()
.Where(s => !string.IsNullOrEmpty(s)).Distinct().ToList();// 去除空字符串 ,去除重复项。 转换为列表
int i = 1;
foreach (var g in smpList)
{
FiltrateInfoList.Add(new GlassLabeInfoMode { Sid = i++, ReagentName = g });
}
}
else
{
FiltrateName = "全部";
}
IsCanSeltctedItem = true;
}
}
}
/// <summary>
/// 过滤玻片信息
/// </summary>
public ObservableCollection<UC_GlassInfo> FiltrateGlassInfo //filtrateGlassInfo
{
get => filtrateGlassInfo;
set
{
if (filtrateGlassInfo != value)
{
if (filtrateGlassInfo != null)
{
foreach (var item in filtrateGlassInfo)
{
item.PropertyChanged -= OnGlassItemPropertyChanged;
}
}
SetProperty(ref filtrateGlassInfo, value);
foreach (var item in filtrateGlassInfo)
{
item.PropertyChanged += OnGlassItemPropertyChanged;
}
// 创建过滤视图
FilteredGlassInfoView = CollectionViewSource.GetDefaultView(filtrateGlassInfo);
FilteredGlassInfoView.Filter = FilterGlassItems;
}
}
}
private ICollectionView _filteredGlassInfoView;
public ICollectionView FilteredGlassInfoView
{
get => _filteredGlassInfoView;
private set => SetProperty(ref _filteredGlassInfoView, value);
}
// 监听每个项的属性变化
private void OnGlassItemPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(UC_GlassInfo.IsShow))
{
FilteredGlassInfoView?.Refresh();// 当 IsShow 变化时刷新视图
}
}
// 过滤逻辑
private bool FilterGlassItems(object item)
{
if (item is UC_GlassInfo glass)
{
return glass.IsShow;
}
return false;
}
public UC_GlassInfo SelectedGlassInfo { get => selectedGlassInfo; set { selectedGlassInfo = value; OnPropertyChanged(); } }
/// <summary>
/// 移除玻片
/// </summary>
/// <param name="number"></param>
private void RemoveGlass(int number)
{
try
{
var dispatcher = Application.Current?.Dispatcher;
if (dispatcher == null && !Dispatcher.CurrentDispatcher.CheckAccess())
{
// 后台线程且没有UI上下文
return;
}
(dispatcher ?? Dispatcher.CurrentDispatcher).Invoke(() =>
{
number--;
if (GlassStationList[number].GlassId.Length > 5)
{
var itemToRemove = FiltrateGlassInfo.FirstOrDefault(x => x.GlassId == GlassStationList[number].GlassId);
if (itemToRemove != null)
{
itemToRemove.IsLoad = false;
itemToRemove.IsShow = true;
}
SelectedGlassListOverEvent.Invoke(GlassStationList.Select(x => x.GlassId).ToList());
}
});
}
catch (Exception ex)
{ }
}
private void AddGlassToModule(KeyValuePair<string, string> gls)
{
try
{
var dispatcher = Application.Current?.Dispatcher;
if (dispatcher == null && !Dispatcher.CurrentDispatcher.CheckAccess())
{
// 后台线程且没有UI上下文
return;
}
(dispatcher ?? Dispatcher.CurrentDispatcher).Invoke(() =>
{
for (int i = 0; i < GlassStationList.Count; i++)
{
if (i >= GlassStationSelectedIndex)
{
if (GlassStationList[i].IsError == false && GlassStationList[i].CategoryName.Length < 2)
{
GlassStationList[i].GlassId = gls.Key;
GlassStationList[i].CategoryName = gls.Value;
var itemToRemove = FiltrateGlassInfo.FirstOrDefault(x => x.GlassId == gls.Key);
if (itemToRemove != null)
{
itemToRemove.IsLoad = true;
itemToRemove.IsShow = false;
}
SelectedGlassListOverEvent.Invoke(GlassStationList.Select(x => x.GlassId).ToList());
break;
}
}
}
});
}
catch (Exception ex)
{
}
}
private void LoadFormDB()
{
int i = 1;
using (var context = new MyContext())
{
var glassData = context.Glasses.Where(x => x.IsPrinted && !x.IsDeleted && !x.IsFinished).OrderByDescending(x => x.Id)
.Select(gls => new // 投影所需字段(非完整实体)
{
gls.GlassId,
gls.DbSample.SampleId,
SampleName = gls.DbSample.Name,
Issequence = gls.ColorMethodEnum == ColorMethod.顺次双染,
Category1Name = gls.ReagentGroup1.ContainsCategory ? gls.ReagentGroup1.FirstAntibodyName :
gls.RgCategory1 != null ? gls.RgCategory1.Name : "错误",
Category2Name = gls.ReagentGroup2 == null ? "无试剂" : gls.ReagentGroup2.ContainsCategory ?
gls.ReagentGroup2.FirstAntibodyName : gls.RgCategory2 != null ? gls.RgCategory2.Name : "错误",
}).AsNoTracking().ToList(); // 声明不跟踪变更
// 单次查询获取所有数据
// 内存中处理复杂逻辑(避免数据库无法翻译的操作)
foreach (var item in glassData)
{
string finalReagentName = item.Category1Name;
if (item.Issequence) // 处理顺次双染逻辑
{
finalReagentName += "*" + item.Category2Name;
}
FiltrateGlassInfo.Add(new UC_GlassInfo { CategoryName = finalReagentName, GlassId = item.GlassId, SampleId = item.SampleId });
FiltrateGlassInfo.AddGlassAction += AddGlassToModule;
}
}
}
}
public class GlassLabeInfoMode : ObservableObject
{
private string reagentName;
private int sid;
private string sampleName;
public string GlassID { get; set; }
public string ReagentName { get { return reagentName; } set { reagentName = value; OnPropertyChanged(); } }
public int Sid { get => sid; set { sid = value; OnPropertyChanged(); } }
public string SampleName { get => sampleName; set { sampleName = value; OnPropertyChanged(); } }
}
目前上述程序运行功能上没有问题。帮我检查一下整个程序这样写有没有问题?能否更简化一些,还有我在操作的时候感觉会有点卡顿,例如在Wd_GlassInfoAdd界面,双击SelectedGlassInfo使之上载到GlassStationList,能感觉到明显的卡顿,如何解决?或者说有没有更好的方案来实现目前的功能?把改进后的代码发一下,我要做详细对比
最新发布