首页 > 其他分享 >【WPF】ListView绑定自定义的ObservableDictionary,绑定 DataTemplate内的控件时候,命令会失效

【WPF】ListView绑定自定义的ObservableDictionary,绑定 DataTemplate内的控件时候,命令会失效

时间:2022-09-24 10:45:31浏览次数:55  
标签:控件 string 自定义 OnPropertyChanged void 绑定 key using public

自定义类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

相关文章

  • 自定义校验器 - 多字段联合校验
    @MinMaxprivateBooleangetMinMaxValidate(){if(maxWidth==null||minWidth==null){returnfalse;}......
  • VUE v-bind 数据绑定
    动态的绑定一个或多个attribute,也可以是组件的prop。缩写: : 或者 . (当使用 .prop 修饰符)期望: any(带参数)|Object(不带参数)参数: attrOrProp(可选的)......
  • 自定义的配置文件,如何注入到SpringBoot?
    一、简介在实际的项目开发过程中,我们经常需要将某些变量从代码里面抽离出来,放在配置文件里面,以便更加统一、灵活的管理服务配置信息。比如,数据库、eureka、zookeeper、redi......
  • 自定义导航栏时
    <template> <view> <u-navbar:is-back="false"title="":background="background"> </u-navbar> <viewclass="content"> <!--正文内容--> </view> <......
  • SAP UI5 SimpleForm 控件的 adjustLabelSpan 属性
    我们在SAPUI5应用开发时,在XML视图里使用SimpleForm控件,会定义其adjustLabelSpan属性。如果设置,labelSpanL和labelSpanM的使用取决于一行中FormContainer的......
  • java自定义导出Excel格式
    使用apache的poi自定义格式导出Excelpom.xml<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.17......
  • Compose控件占满剩余空间
    Row(Modifier.fillMaxWidth().height(30.dp)){Icon(Icons.Filled.Add,"",Modifier.size(20.dp))Text("Text",Modifier.weight(1f))/......
  • C#中使用Invoke和BeginInvoke跨线程更新UI控件示例代码
    在多线程开发过程中,有时候需要更新UI控件内容,但是在c#多线程Task、Thread、BackgroundWork中不能直接更新UI控件,否则会报调用线程不能访问此对象,因为它由另一个线程拥有The......
  • Linux添加Systemd自定义服务
    以nginx为例使用yum命令安装的nginxSystemd服务文件以.service结尾,比如现在要建立nginx为开机启动,如果用yuminstall命令安装的,yum命令会自动创建nginx.service文件,直接......
  • vue+echart+自定义指令:自适应图表
    vue+echart+自定义指令:自适应图表,图表根据宽高拉伸变化而重置变化。之前有用到过其它方式实现,现在只用指令来实现:<template><divclass="box"><divref="zhex"v-res......