自定义类ObservableDictionary
注意:
(1)绑定字典时候要用Value.字段例如: Text="{Binding Value.Close, StringFormat={}{0:F2}}">, StringFormat={}{0:F2}是格式化字段
using System; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Spider.Comment { using System; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Runtime.CompilerServices; namespace ObservableDictionary { public delegate void NotifyDictionaryChangedEventHandler(object sender, NotifyDictionaryChangedEventArgs e); public class NotifyDictionaryChangedEventArgs { public NotifyCollectionChangedAction Action { get; } public object AddedKey { get; } public object AddedItem { get; } public object RemovedKey { get; } public object RemovedItem { get; } public NotifyDictionaryChangedEventArgs(NotifyCollectionChangedAction action) { this.Action = action; } public NotifyDictionaryChangedEventArgs(NotifyCollectionChangedAction action, object changedItem, object key) { this.Action = action; this.AddedItem = changedItem; this.AddedKey = key; } public NotifyDictionaryChangedEventArgs(NotifyCollectionChangedAction action, object addedItem, object addedKey, object removedItem, object removedKey) { this.Action = action; this.AddedItem = addedItem; this.AddedKey = addedKey; this.RemovedItem = removedItem; this.RemovedKey = removedKey; } } public interface INotifyDictionaryChanged { event NotifyDictionaryChangedEventHandler DictionaryChanged; } public interface IObservableMap<TValue> : IEnumerable<KeyValuePair<string, TValue>>, INotifyDictionaryChanged { TValue this[string key] { get; set; } bool ContainsKey(string key); void Remove(string key); void Add(string key, TValue value); } public class ObservableStringDictionary<TValue> : Dictionary<string, TValue>, IObservableMap<TValue>, INotifyDictionaryChanged, INotifyPropertyChanged { #region public public new TValue this[string key] { get => base[key]; set { base[key] = value; this.OnPropertyChanged(CountString); this.OnPropertyChanged(IndexerNameBeg + IndexerNameEnd); this.OnPropertyChanged(IndexerNameBeg + key + IndexerNameEnd); this.OnCollectionChanged(NotifyCollectionChangedAction.Reset, key, value); } } public new void Add(string key, TValue value) { base.Add(key, value); this.OnPropertyChanged(CountString); this.OnPropertyChanged(IndexerNameBeg + IndexerNameEnd); this.OnPropertyChanged(IndexerNameBeg + key + IndexerNameEnd); this.OnCollectionChanged(NotifyCollectionChangedAction.Add, key, value); } public new void Clear() { base.Clear(); this.OnPropertyChanged(CountString); this.OnPropertyChanged(IndexerNameBeg + IndexerNameEnd); this.OnCollectionReset(); } public new void Remove(string key) { TValue removedItem = this[key]; base.Remove(key); this.OnPropertyChanged(CountString); this.OnPropertyChanged(IndexerNameBeg + IndexerNameEnd); this.OnPropertyChanged(IndexerNameBeg + key + IndexerNameEnd); this.OnCollectionChanged(NotifyCollectionChangedAction.Remove, key, removedItem); } event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged { add => this.PropertyChanged += value; remove => this.PropertyChanged -= value; } #if !FEATURE_NETCORE [field: NonSerializedAttribute()] #endif public virtual event NotifyDictionaryChangedEventHandler DictionaryChanged; #if !FEATURE_NETCORE [field: NonSerializedAttribute()] #endif protected virtual event PropertyChangedEventHandler PropertyChanged; private void OnCollectionChanged(NotifyCollectionChangedAction action, string key, TValue value) { this.OnCollectionChanged(new NotifyDictionaryChangedEventArgs(action, value, key)); } protected virtual void OnCollectionChanged(NotifyDictionaryChangedEventArgs e) { if (this.DictionaryChanged is null) return; using (this.BlockReentrancy()) { this.DictionaryChanged(this, e); } } protected IDisposable BlockReentrancy() { this._monitor.Enter(); return this._monitor; } protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) { this.PropertyChanged?.Invoke(this, e); } #endregion #region private private void OnPropertyChanged(string propertyName) { this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } private void OnCollectionReset() { this.OnCollectionChanged(new NotifyDictionaryChangedEventArgs(NotifyCollectionChangedAction.Reset)); } #endregion Private Methods #region Private Types // this class helps prevent reentrant calls #if !FEATURE_NETCORE [Serializable()] [TypeForwardedFrom("WindowsBase, Version=3.0.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")] #endif private class SimpleMonitor : IDisposable { public void Enter() { ++this._busyCount; } public void Dispose() { --this._busyCount; } public bool Busy { get => this._busyCount > 0; } int _busyCount; } #endregion Private Types #region Private Fields private const string CountString = "Count"; // This must agree with Binding.IndexerName. It is declared separately // here so as to avoid a dependency on PresentationFramework.dll. private const string IndexerNameBeg = "Item["; private const string IndexerNameEnd = "]"; private SimpleMonitor _monitor = new SimpleMonitor(); #endregion Private Fields } } }
绑定ListView,
注意
(1)绑定<DataTemplate>内的控件时候,命令会失效,要把命令直接绑定到 元数据所绑定的控件的DataContext上
一定要这样写Command="{Binding DataContext.AddSelfselectionStockCommand, ElementName=dashboard ,Mode=TwoWay}"
(2)、<DataTemplate>标签内的命令 ,要使用路由命令或者自定义命令连接到命令管理器如下:
public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } }
<ListView ItemContainerStyle="{DynamicResource ListViewItemContainerStyle}" ItemsSource="{Binding AllBoardStocksData}" VirtualizingPanel.VirtualizationMode="Recycling" VirtualizingPanel.IsVirtualizing="True" Background="Transparent" BorderThickness="0" > <ListView.View > <GridView ColumnHeaderContainerStyle="{DynamicResource ColumnHeaderContainerStyle}" > <GridViewColumn Width="100"> <GridViewColumnHeader Style="{DynamicResource HeaderGridViewColumnHeaderStyle}" Cursor="Hand" Content="代码" /> <GridViewColumn.CellTemplate > <DataTemplate > <TextBlock Margin="10" Background="Gray" Text="{Binding Value.Code}"></TextBlock> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Header="名称" DisplayMemberBinding="{Binding Value.Name }" /> <GridViewColumn Header="现价"> <GridViewColumn.CellTemplate> <DataTemplate> <TextBlock x:Name="CloseTextBoxStyle" Text="{Binding Value.Close, StringFormat={}{0:F2}}"></TextBlock> <DataTemplate.Triggers> <DataTrigger Binding="{Binding Value.Chg_rate, Converter={StaticResource IntToboolConverter}}" Value="true"> <Setter TargetName="CloseTextBoxStyle" Property="Foreground" Value="red"/> </DataTrigger> <DataTrigger Binding="{Binding Value.Chg_rate, Converter={StaticResource IntToboolConverter}}" Value="false"> <Setter TargetName="CloseTextBoxStyle" Property="Foreground" Value=" green"/> </DataTrigger> </DataTemplate.Triggers> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Header="涨跌幅"> <GridViewColumn.CellTemplate> <DataTemplate> <TextBlock x:Name="UpDowpTextBoxStyle" Text="{Binding StringFormat={}{0}%,Path= Value.Chg_rate}"></TextBlock> <DataTemplate.Triggers> <DataTrigger Binding="{Binding Value.Chg_rate, Converter={StaticResource IntToboolConverter}}" Value="true"> <Setter TargetName="UpDowpTextBoxStyle" Property="Foreground" Value="red"/> </DataTrigger> <DataTrigger Binding="{Binding Value.Chg_rate, Converter={StaticResource IntToboolConverter}}" Value="false"> <Setter TargetName="UpDowpTextBoxStyle" Property="Foreground" Value=" green"/> </DataTrigger> </DataTemplate.Triggers> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Header="总市值(亿)" DisplayMemberBinding="{Binding Value.TotalValue,StringFormat=000.000E+0010}" /> <GridViewColumn Header="加入自选股"> <GridViewColumn.CellTemplate> <DataTemplate> <CheckBox Name="isselectstock" IsThreeState="False" IsChecked="{Binding Value.IsSelfselectionStock }" Command="{Binding DataContext.AddSelfselectionStockCommand, ElementName=dashboard ,Mode=TwoWay}" > <CheckBox.CommandParameter> <MultiBinding Converter="{StaticResource CodeAndCheckboxStateMultiConverter}"> <Binding Path="IsChecked" ElementName="isselectstock"/> <Binding Path="Value.Code" /> </MultiBinding> </CheckBox.CommandParameter> </CheckBox> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Header="详情"> <GridViewColumn.CellTemplate> <DataTemplate> <Button >详情</Button> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> </GridView> </ListView.View> </ListView>
标签:控件,string,自定义,OnPropertyChanged,void,绑定,key,using,public From: https://www.cnblogs.com/cdaniu/p/16725101.html