




















public class ProxyBinding : Freezable { protected override Freezable CreateInstanceCore() { return new ProxyBinding(); } public object SourceObject { get { return (object)GetValue(SourceObjectProperty); } set { SetValue(SourceObjectProperty, value); } } // Using a DependencyProperty as the backing store for SourceObject. This enables animation, styling, binding, etc... public static readonly DependencyProperty SourceObjectProperty = DependencyProperty.Register( nameof(SourceObject), typeof(object), typeof(ProxyBinding), new PropertyMetadata(null)); } <UserControl.Resources> <local:ProxyBinding x:Key="ProxyBinding" SourceObject="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}"/> </UserControl.Resources> <ContextMenu> <MenuItem Header="{Binding SourceObject.UCFirstMIHeader, Source={StaticResource ProxyBinding}}" Command="{Binding SourceObject.UCFirstMICmd, Source={StaticResource ProxyBinding}}"/> </ContextMenu>
<MenuItem Header="{Binding SourceObject.UCFirstMIHeader, Source={StaticResource ProxyBinding}}" Command="{Binding SourceObject.UCFirstMICmd, Source={StaticResource ProxyBinding}}"/>
<UserControl x:Class="WpfApp6.UCDG" 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:local="clr-namespace:WpfApp6" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <UserControl.Resources> <local:ProxyBinding x:Key="ProxyBinding" SourceObject="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}"/> </UserControl.Resources> <Grid> <DataGrid ItemsSource="{Binding UCDGCollection, RelativeSource={RelativeSource AncestorType=UserControl}}" AutoGenerateColumns="True" VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling" VirtualizingPanel.CacheLength="5,5" VirtualizingPanel.CacheLengthUnit="Item" ScrollViewer.IsDeferredScrollingEnabled="True" ScrollViewer.CanContentScroll="True" EnableRowVirtualization="True" EnableColumnVirtualization="True" UseLayoutRounding="True" SnapsToDevicePixels="True" IsReadOnly="True"> <DataGrid.Resources> <Style TargetType="DataGridRow"> <Setter Property="FontSize" Value="30"/> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="FontSize" Value="50"/> <Setter Property="Foreground" Value="Red"/> </Trigger> </Style.Triggers> </Style> </DataGrid.Resources> <DataGrid.ContextMenu> <ContextMenu> <MenuItem Header="{Binding SourceObject.UCFirstMIHeader, Source={StaticResource ProxyBinding}}" Command="{Binding SourceObject.UCFirstMICmd, Source={StaticResource ProxyBinding}}"/> </ContextMenu> </DataGrid.ContextMenu> </DataGrid> </Grid> </UserControl> using System; using System.Collections; using System.Collections.Generic; using System.Reflection.Metadata; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfApp6 { /// <summary> /// Interaction logic for UCLbx.xaml /// </summary> public partial class UCDG : UserControl { public UCDG() { InitializeComponent(); } public IList UCDGCollection { get { return (IList)GetValue(UCDGCollectionProperty); } set { SetValue(UCDGCollectionProperty, value); } } // Using a DependencyProperty as the backing store for UCDGCollection. This enables animation, styling, binding, etc... public static readonly DependencyProperty UCDGCollectionProperty = DependencyProperty.Register( nameof(UCDGCollection), typeof(IList), typeof(UCDG), new PropertyMetadata(null)); public string UCFirstMIHeader { get { return (string)GetValue(UCFirstMIHeaderProperty); } set { SetValue(UCFirstMIHeaderProperty, value); } } // Using a DependencyProperty as the backing store for UCFirstMIHeader. This enables animation, styling, binding, etc... public static readonly DependencyProperty UCFirstMIHeaderProperty = DependencyProperty.Register( nameof(UCFirstMIHeader), typeof(string), typeof(UCDG), new PropertyMetadata(null)); public DelCmd UCFirstMICmd { get { return (DelCmd)GetValue(UCFirstMICmdProperty); } set { SetValue(UCFirstMICmdProperty, value); } } // Using a DependencyProperty as the backing store for UCFirstMICmd. This enables animation, styling, binding, etc... public static readonly DependencyProperty UCFirstMICmdProperty = DependencyProperty.Register( nameof(UCFirstMICmd), typeof(DelCmd), typeof(UCDG), new PropertyMetadata(null)); } public class ProxyBinding : Freezable { protected override Freezable CreateInstanceCore() { return new ProxyBinding(); } public object SourceObject { get { return (object)GetValue(SourceObjectProperty); } set { SetValue(SourceObjectProperty, value); } } // Using a DependencyProperty as the backing store for SourceObject. This enables animation, styling, binding, etc... public static readonly DependencyProperty SourceObjectProperty = DependencyProperty.Register( nameof(SourceObject), typeof(object), typeof(ProxyBinding), new PropertyMetadata(null)); } public class DelCmd : ICommand { private Action<object?> execute; private Func<object?, bool>? canExecute; public DelCmd(Action<object?> executeValue, Func<object?, bool>? canExecuteValue=null) { execute = executeValue ?? throw new ArgumentNullException(nameof(executeValue)); canExecute= canExecuteValue; } public event EventHandler? CanExecuteChanged; public bool CanExecute(object? parameter) { return canExecute == null ? true : canExecute(parameter); } public void Execute(object? parameter) { if(!CanExecute(parameter)) { return; } execute?.Invoke(parameter); } public void RaiseCanExecuteChanged() { var handler = Volatile.Read(ref CanExecuteChanged); if (handler == null) { return; } if (Application.Current?.Dispatcher?.CheckAccess() == true) { handler?.Invoke(this, EventArgs.Empty); } else { Application.Current?.Dispatcher?.Invoke(() => { handler?.Invoke(this, EventArgs.Empty); }); } } } } <Window x:Class="WpfApp6.MainWindow" 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:local="clr-namespace:WpfApp6" mc:Ignorable="d" Title="{Binding MainTitle}" WindowState="Maximized"> <Window.DataContext> <local:MainVM/> </Window.DataContext> <Grid> <local:UCDG UCDGCollection="{Binding BooksCollection}" UCFirstMIHeader="{Binding FirstHeader}" UCFirstMICmd="{Binding FirstMICmd}" /> </Grid> </Window> using System.Collections.ObjectModel; using System.ComponentModel; using System.Net.Http; using System.Runtime.CompilerServices; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using Newtonsoft.Json; namespace WpfApp6 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } } public class MainVM : INotifyPropertyChanged { string originalUrl = "http://localhost:8080/getbookslist?count="; HttpClient client; private bool isLoadind = false; private object loadingObj = new object(); public MainVM() { if(!DesignerProperties.GetIsInDesignMode(new DependencyObject())) { client = new HttpClient(); Task.Run(async () => { await LoadDataFromServerRelentless(); }); } } private async Task LoadDataFromServerRelentless() { while (true) { await InitBooksCollectionAsync(); await Task.Delay(20000); } } private async Task InitBooksCollectionAsync(int cnt=1000000) { lock(loadingObj) { if(isLoadind) { return; } isLoadind = true; } try { await Application.Current?.Dispatcher?.InvokeAsync(() => { MainTitle = $"{DateTime.Now.ToString("yyyyMMddHHmmssffff")},loading..."; BooksCollection?.Clear(); }); string requestUrl = $"{originalUrl}{cnt}"; string jsonStr = await client.GetStringAsync(requestUrl).ConfigureAwait(false); if (!string.IsNullOrWhiteSpace(jsonStr)) { List<Book>? bksList = Newtonsoft.Json.JsonConvert. DeserializeObject<List<Book>>(jsonStr); if (bksList != null && bksList.Any()) { await Application.Current?.Dispatcher?.InvokeAsync(() => { BooksCollection = new ObservableCollection<Book>(bksList); MainTitle = $"{DateTime.Now.ToString("yyyyMMddHHmmssffff")}," + $"loaded {BooksCollection?.Count} items," + $"first Id:{BooksCollection[0]?.Id}," + $"Last Id:{BooksCollection[^1]?.Id}"; }, System.Windows.Threading.DispatcherPriority.Background); } } } catch (Exception ex) { #if DEBUG System.Diagnostics.Debug.WriteLine($"{DateTime.Now},{ex?.Message}"); #else System.Diagnostics.Trace.WriteLine($"{DateTime.Now},{ex?.Message}"); #endif } finally { isLoadind = false; } } private ICommand firstMICmd; public ICommand FirstMICmd { get { if(firstMICmd==null) { firstMICmd = new DelCmd(FirstMICmdExecuted); } return firstMICmd; } } private void FirstMICmdExecuted(object? obj) { } private string firstHeader="First Header"; public string FirstHeader { get { return firstHeader; } set { if(value!=firstHeader) { firstHeader = value; OnPropertyChanged(); } } } private string mainTitle = $"{DateTime.Now.ToString("yyyyMMddHHmmssffff")}"; public string MainTitle { get { return mainTitle; } set { if(value!=mainTitle) { mainTitle = value; OnPropertyChanged(); } } } private ObservableCollection<Book> booksCollection; public ObservableCollection<Book> BooksCollection { get { return booksCollection; } set { if(value!=booksCollection) { booksCollection = value; OnPropertyChanged(); } } } public event PropertyChangedEventHandler? PropertyChanged; private void OnPropertyChanged([CallerMemberName] string propName="") { var handler = Volatile.Read(ref PropertyChanged); if (handler == null) { return; } handler?.Invoke(this, new PropertyChangedEventArgs(propName)); } } public class Book { public int Id { get; set; } public string Name { get; set; } public string ISBN { get; set; } public string Author { get; set; } public string Comment { get; set; } public string Content { get; set; } public string Summary { get; set; } public string Title { get; set; } public string Topic { get; set; } } }






此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。