DependencyProperty 未在 NotifyCollectionChanged 事件上通知 UI

2024-02-13

我正在使用一个自定义控件,该控件具有选定的项目依赖属性,我已将其连接到集合更改事件,但未通知 UI 并且 PropertyChanged 事件始终为空。通常我会说这是一个数据上下文问题。但我无法更改控件上的数据上下文,因为不会显示任何数据。

    public ObservableCollection<object> SelectedItems
    {
        get { return (ObservableCollection<object>)GetValue(SelectedItemsProperty); }
        set { SetValue(SelectedItemsProperty, value); }
    }

    // Using a DependencyProperty as the backing store for SelectedItems.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SelectedItemsProperty =
        DependencyProperty.RegisterAttached("SelectedItems", typeof(ObservableCollection<object>), 
        typeof(MultiSelectComboBox), 
        new System.Windows.PropertyMetadata(new ObservableCollection<object>(), new PropertyChangedCallback(SelectedItemsPropertyChanged)));

    private static void SelectedItemsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        MultiSelectComboBox relay = d as MultiSelectComboBox;
        if (e.OldValue != null)
        {
            var coll = (INotifyCollectionChanged)e.OldValue;
            coll.CollectionChanged -= relay.SelectedItemsCollectionChanged;
        }
        if (e.NewValue != null)
        {
            var coll = (INotifyCollectionChanged)e.NewValue;
            coll.CollectionChanged += relay.SelectedItemsCollectionChanged;
        }
    }

上面是它在 xaml 中绑定到 ViewModel 上的 ObservableCollection 的属性声明。我缺少什么。该控件实现 INotifyPropertyChanged。

我在下面添加了更多代码。这是原始代码,我想将相同的属性更改为依赖属性以绑定到集合目的。

    namespace Kepler.SilverlightControls.MultiSelectComboBox
    {
/// <summary>
/// MultiSelect ComboBox
/// </summary>
public class MultiSelectComboBox : Telerik.Windows.Controls.RadComboBox,    INotifyPropertyChanged
{
    #region Events

    /// <summary>
    /// Est appelé quand une propriété change
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

    #region Constructor

    /// <summary>
    /// Initializes a new instance of MultiSelectComboBox
    /// </summary>
    public MultiSelectComboBox()
    {
        ClearSelectionButtonVisibility = Visibility.Collapsed;

        string xaml = @"<DataTemplate 
            xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
            xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
            xmlns:local=""clr-namespace:Kepler.SilverlightControls.MultiSelectComboBox;assembly=Kepler.SilverlightControls"">
            <TextBlock TextWrapping=""Wrap"" local:MultiSelectComboBoxService.SelectionBoxLoaded=""True"" />
            </DataTemplate>";

        var selectionBoxTemplate = (DataTemplate)XamlReader.Load(xaml);
        SelectionBoxTemplate = selectionBoxTemplate;
        EmptySelectionBoxTemplate = selectionBoxTemplate;

        xaml = @"<DataTemplate 
            xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
            xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""    
            xmlns:local=""clr-namespace:Kepler.SilverlightControls.MultiSelectComboBox;assembly=Kepler.SilverlightControls"">
            <CheckBox local:MultiSelectComboBoxService.ComboBoxItemLoaded=""True"" 
                IsChecked=""{Binding Path=(local:MultiSelectComboBoxService.IsChecked), Mode=TwoWay, RelativeSource={RelativeSource Self}}"" />
            </DataTemplate>";
        ItemTemplate = (DataTemplate)XamlReader.Load(xaml);
    }

    #endregion

    #region Propriétés

    /// <summary>
    /// IsCheckedBindingPath Property
    /// </summary>
    public string IsCheckedBindingPath
    {
        get { return (string)GetValue(IsCheckedBindingPathProperty); }
        set { SetValue(IsCheckedBindingPathProperty, value); }
    }

    // Using a DependencyProperty as the backing store for IsCheckedBindingPath.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsCheckedBindingPathProperty =
        DependencyProperty.Register("IsCheckedBindingPath", typeof(string), typeof(MultiSelectComboBox), new PropertyMetadata(null, (obj, e) =>
        {
            Telerik.Windows.Controls.TextSearch.SetTextPath(obj, e.NewValue as string);
        }));



    /// <summary>
    /// DisplayBindingPath Property
    /// </summary>
    public static readonly DependencyProperty DisplayBindingPathProperty = DependencyProperty.Register(
       "DisplayBindingPath", typeof(string), typeof(MultiSelectComboBox), new PropertyMetadata(null, (obj, e) =>
       {
           Telerik.Windows.Controls.TextSearch.SetTextPath(obj, e.NewValue as string);
       }));
    /// <summary>
    /// Gets or sets the display member path (we can't reuse DisplayMemberPath property)
    /// </summary>
    public string DisplayBindingPath
    {
        get { return GetValue(DisplayBindingPathProperty) as string; }
        set { SetValue(DisplayBindingPathProperty, value); }
    }

    private ObservableCollection<object> _selectedItems;
    /// <summary>
    /// Gets the selected items
    /// </summary>
    public ObservableCollection<object> SelectedItems
    {
        get
        {
            if (_selectedItems == null)
            {
                _selectedItems = new ObservableCollection<object>();
                _selectedItems.CollectionChanged += new NotifyCollectionChangedEventHandler(SelectedItemsCollectionChanged);
            }
            return _selectedItems;
        }
    }

    private ObservableCollection<object> _selectedValues;
    /// <summary>
    /// Gets the selected values
    /// </summary>
    public ObservableCollection<object> SelectedValues
    {
        get
        {
            if (_selectedValues == null)
            {
                _selectedValues = new ObservableCollection<object>();
                _selectedValues.CollectionChanged += new NotifyCollectionChangedEventHandler(SelectedValuesCollectionChanged);
            }
            return _selectedValues;
        }
    }

    #endregion

    #region Methods

    /// <summary>
    /// Called when the Items property changed
    /// </summary>
    /// <param name="e">change informations</param>
    protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
    {
        base.OnItemsChanged(e);

        int idx;
        var selectedItems = SelectedItems;

        switch (e.Action)
        {
            case NotifyCollectionChangedAction.Add:
            case NotifyCollectionChangedAction.Replace:
            case NotifyCollectionChangedAction.Reset:
                var items = e.NewItems;
                if (items == null)
                {
                    var selected = new List<object>();
                    foreach (var item in this.ItemsSource)
                    {
                        PropertyInfo isCheckedBindingPathProperty = this.IsCheckedBindingPath != null ? item.GetType().GetProperty(this.IsCheckedBindingPath) : null;
                        if (isCheckedBindingPathProperty != null
                            && (bool)isCheckedBindingPathProperty.GetValue(item,null) == true)
                        {
                            selected.Add(item);
                            SelectedValues.Add(item.GetType().GetProperty(SelectedValuePath).GetValue(item, null));
                        }
                    }
                    items = selected;
                }
                if (items != null)
                {
                    foreach (object value in SelectedValues)
                    {
                        foreach (object item in items)
                        {
                            if (GetSelectedValue(item).Equals(value) && !selectedItems.Contains(item))
                            {
                                selectedItems.Add(item);
                            }
                        }
                    } 
                }
                break;
            case NotifyCollectionChangedAction.Remove:
                foreach (object item in e.OldItems)
                {
                    idx = selectedItems.IndexOf(item);
                    if (idx >= 0)
                    {
                        selectedItems.RemoveAt(idx);
                    }
                }
                break;
        }
    }

    private void RemoveCollectionChangedEvents()
    {
        SelectedItems.CollectionChanged -= new NotifyCollectionChangedEventHandler(SelectedItemsCollectionChanged);
        SelectedValues.CollectionChanged -= new NotifyCollectionChangedEventHandler(SelectedValuesCollectionChanged);
    }

    private void AddCollectionChangedEvents()
    {
        SelectedItems.CollectionChanged += new NotifyCollectionChangedEventHandler(SelectedItemsCollectionChanged);
        SelectedValues.CollectionChanged += new NotifyCollectionChangedEventHandler(SelectedValuesCollectionChanged);
    }

    private void SelectedItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (SelectedValuePath != null)
        {
            RemoveCollectionChangedEvents();
            try
            {
                switch (e.Action)
                {
                    case NotifyCollectionChangedAction.Add:
                        AddSelectedValues(e.NewItems);
                        break;
                    case NotifyCollectionChangedAction.Remove:
                        RemoveSelectedValues(e.OldItems);
                        break;
                    case NotifyCollectionChangedAction.Replace:
                        RemoveSelectedValues(e.OldItems);
                        AddSelectedValues(e.NewItems);
                        break;
                    case NotifyCollectionChangedAction.Reset:
                        SelectedValues.Clear();
                        foreach (object item in Items)
                        {
                            UpdateSelectedItem(item, false);
                        }
                        AddSelectedValues(e.NewItems);
                        break;
                }
            }
            finally
            {
                AddCollectionChangedEvents();
            }
        }
        RaiseSelectedItemsPropertyChanged();
    }

    private void RemoveSelectedValues(IList items)
    {
        foreach (var item in items)
        {
            SelectedValues.Remove(GetSelectedValue(item));
            UpdateSelectedItem(item, false);
        }
    }

    private void AddSelectedValues(IList items)
    {
        if (items != null)
        {
            object selectedValue;
            foreach (var item in items)
            {
                selectedValue = GetSelectedValue(item);
                if (!SelectedValues.Contains(selectedValue))
                {
                    SelectedValues.Add(selectedValue);
                }
                UpdateSelectedItem(item, true);
            }
        }
    }

    private object GetSelectedValue(object item)
    {
        return DataControlHelper.GetPropertyInfo(item.GetType(), SelectedValuePath).GetValue(item, null);
    }

    private void SelectedValuesCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        RemoveCollectionChangedEvents();
        try
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    AddSelectedItems(e.NewItems);
                    break;
                case NotifyCollectionChangedAction.Remove:
                    RemoveSelectedItems(e.OldItems);
                    break;
                case NotifyCollectionChangedAction.Replace:
                    RemoveSelectedItems(e.OldItems);
                    AddSelectedItems(e.NewItems);
                    break;
                case NotifyCollectionChangedAction.Reset:
                    var selectedItems = SelectedItems.ToList();
                    SelectedItems.Clear();
                    foreach (object item in selectedItems)
                    {
                        UpdateSelectedItem(item, false);
                    }
                    AddSelectedItems(e.NewItems);
                    break;
            }
        }
        finally
        {
            AddCollectionChangedEvents();
        }
        RaiseSelectedItemsPropertyChanged();
    }

    private void RaiseSelectedItemsPropertyChanged()
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs("SelectedItems"));
            // To update the selection box
        }
    }

    private void RemoveSelectedItems(IList values)
    {
        object item;
        foreach (var value in values)
        {
            item = SelectedItems.FirstOrDefault(e => GetSelectedValue(e).Equals(value));
            if (item != null)
            {
                SelectedItems.Remove(item);
                UpdateSelectedItem(item, false);
            }
        }
    }

    private void AddSelectedItems(IList values)
    {
        if (values != null)
        {
            object item;
            foreach (var value in values)
            {
                item = Items.FirstOrDefault(e => GetSelectedValue(e).Equals(value));
                if (item != null)
                {
                    SelectedItems.Add(item);
                    UpdateSelectedItem(item, true);
                }
            }
        }
    }

    private void UpdateSelectedItem(object item, bool select)
    {
        var obj = ItemContainerGenerator.ContainerFromItem(item);
        if (obj != null)
        {
            var cb = obj.FindChildByType<CheckBox>();
            if (cb != null && cb.IsChecked != select)
            {
                cb.IsChecked = select;
            }
        }
    }

    /// <summary>
    /// Create a new ComboBox item
    /// </summary>
    /// <returns>a new ComboBox item</returns>
    protected override DependencyObject GetContainerForItemOverride()
    {
        return new MultiSelectComboBoxItem(this);
    }

    protected override void OnKeyDown(System.Windows.Input.KeyEventArgs e)
    {
        base.OnKeyDown(e);
        IsDropDownOpen = true;
    }

    #endregion
}

}

该服务类别如下:

    namespace Kepler.SilverlightControls.MultiSelectComboBox
    {
/// <summary>
/// Service for the MultiSelect comboBox
/// </summary>
public static class MultiSelectComboBoxService
{
    /// <summary>
    /// IsChecked property
    /// </summary>
    public static DependencyProperty IsCheckedProperty = DependencyProperty.RegisterAttached("IsChecked",
        typeof(bool), typeof(MultiSelectComboBoxService), new PropertyMetadata(false, (obj, e) =>
        {
            MultiSelectComboBoxItem comboBoxItem = obj.GetVisualParent<MultiSelectComboBoxItem>();
            if (comboBoxItem != null)
            {
                MultiSelectComboBox comboBox = comboBoxItem.ParentComboBox;
                var selectedItems = (IList)comboBox.SelectedItems;
                object item = comboBoxItem.DataContext;
                PropertyInfo isCheckedBindingPathProperty = item.GetType().GetProperty(comboBox.IsCheckedBindingPath);
                isCheckedBindingPathProperty.SetValue(item, e.NewValue,null);
                if ((bool)e.NewValue)
                {
                    if (!selectedItems.Contains(item))
                    {
                        selectedItems.Add(item);
                    }
                }
                else
                {
                    selectedItems.Remove(item);
                }
            }
        }));

    /// <summary>
    /// Gets a value indicating if the object is checked or not
    /// </summary>
    /// <param name="obj">DependencyObject</param>
    /// <returns>a value indicating if the object is checked or not</returns>
    public static bool GetIsChecked(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsCheckedProperty);
    }

    /// <summary>
    /// Sets a value indicating if the object is checked or not
    /// </summary>
    /// <param name="obj">DependencyObject</param>
    /// <param name="value">the value indicating if the object is checked or not</param>
    public static void SetIsChecked(DependencyObject obj, bool value)
    {
        obj.SetValue(IsCheckedProperty, value);
    }

    /// <summary>
    /// SelectionBoxLoaded property called on SelectionBox load
    /// </summary>
    public static DependencyProperty SelectionBoxLoadedProperty = DependencyProperty.RegisterAttached("SelectionBoxLoaded",
        typeof(bool), typeof(MultiSelectComboBoxService), new PropertyMetadata(false, (obj, e) =>
        {
            TextBlock targetElement = obj as TextBlock;
            if (targetElement != null)
            {
                targetElement.Loaded += new RoutedEventHandler(targetElement_Loaded);
            }
        }));

    private static void targetElement_Loaded(object sender, RoutedEventArgs e)
    {
        TextBlock targetElement = (TextBlock)sender;
        targetElement.Loaded -= new RoutedEventHandler(targetElement_Loaded);
        MultiSelectComboBox comboBox = targetElement.GetVisualParent<MultiSelectComboBox>();
        if (comboBox != null)
        {
            targetElement.SetBinding(TextBlock.TextProperty, new Binding("SelectedItems")
            {
                Converter = new MultiSelectComboxConverter(),
                Source = comboBox,
                ConverterParameter = comboBox.DisplayBindingPath
            });
        }
    }

    /// <summary>
    /// Gets the value indicating if the object is loaded or not
    /// </summary>
    /// <param name="obj">DependencyObject</param>
    /// <returns>the value indicating if the object is loaded or not</returns>
    public static bool GetSelectionBoxLoaded(DependencyObject obj)
    {
        return (bool)obj.GetValue(SelectionBoxLoadedProperty);
    }

    /// <summary>
    /// Sets the value indicating if the object is loaded or not
    /// </summary>
    /// <param name="obj">DependencyObject</param>
    /// <param name="value">the value indicating if the object is loaded or not</param>
    public static void SetSelectionBoxLoaded(DependencyObject obj, bool value)
    {
        obj.SetValue(SelectionBoxLoadedProperty, value);
    }

    /// <summary>
    /// ComboBoxItemLoaded called on ComboBoxItem load
    /// </summary>
    public static DependencyProperty ComboBoxItemLoadedProperty = DependencyProperty.RegisterAttached("ComboBoxItemLoaded",
        typeof(bool), typeof(MultiSelectComboBoxService), new PropertyMetadata(false, (obj, e) =>
        {
            CheckBox targetElement = obj as CheckBox;
            if (targetElement != null)
            {
                targetElement.Loaded += new RoutedEventHandler(comboBoxItem_Loaded);
                targetElement.SetBinding(MultiSelectComboBoxService.DataContextProperty, new Binding());
            }
        }));

    private static void comboBoxItem_Loaded(object sender, RoutedEventArgs e)
    {
        FrameworkElement element = (FrameworkElement)sender;
        MultiSelectComboBox comboBox = GetComboBox(element);
        if (comboBox != null)
        {
            element.SetBinding(CheckBox.ContentProperty, new Binding(comboBox.DisplayBindingPath));
            //Binding binding = new Binding(comboBox.IsCheckedBindingPath);
            //binding.Mode = BindingMode.TwoWay;
            //element.SetBinding(CheckBox.IsCheckedProperty, binding);
        }
    }

    /// <summary>
    ///Gets the value indicating if the item is loaded or not
    /// </summary>
    /// <param name="obj">DependencyObject</param>
    /// <returns>the value indicating if the item is loaded or not</returns>
    public static bool GetComboBoxItemLoaded(DependencyObject obj)
    {
        return (bool)obj.GetValue(ComboBoxItemLoadedProperty);
    }

    /// <summary>
    /// Sets the value indicating if the item is loaded or not
    /// </summary>
    /// <param name="obj">DependencyObject</param>
    /// <param name="value">the value indicating if the item is loaded or not</param>
    public static void SetComboBoxItemLoaded(DependencyObject obj, bool value)
    {
        obj.SetValue(ComboBoxItemLoadedProperty, value);
    }

    private static MultiSelectComboBox GetComboBox(DependencyObject targetElement)
    {
        MultiSelectComboBoxItem item = targetElement.GetVisualParent<MultiSelectComboBoxItem>();
        if (item != null)
        {
            return item.ParentComboBox;
        }
        return null;
    }

    private static DependencyProperty DataContextProperty = DependencyProperty.RegisterAttached("DataContext",
        typeof(object), typeof(MultiSelectComboBoxService), new PropertyMetadata(null, (obj, e) =>
        {
            CheckBox checkBox = (CheckBox)obj;
            MultiSelectComboBox comboBox = GetComboBox(checkBox);
            if (comboBox != null)
            {
                checkBox.IsChecked = comboBox.SelectedItems.Contains(checkBox.DataContext);
            }
        }));
    private static object GetDataContext(DependencyObject obj)
    {
        return obj.GetValue(DataContextProperty);
    }
    private static void SetDataContext(DependencyObject obj, object value)
    {
        obj.SetValue(DataContextProperty, value);
    }
}

}

转换器如下:

    namespace Kepler.SilverlightControls.MultiSelectComboBox
    {
#region Méthodes
public class MultiSelectComboxConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        string displayMemberPath = parameter as string;
        if (String.IsNullOrWhiteSpace(displayMemberPath))
        {
            return String.Empty;
        }

        PropertyInfo propertyInfo;
        return string.Join(", ", (value as IEnumerable<object>).Select(item =>
            {
                propertyInfo = DataControlHelper.GetPropertyInfo(item.GetType(), displayMemberPath);
                if (propertyInfo == null)
                {
                    return String.Empty;
                }
                return propertyInfo.GetValue(item, null);
            }).ToArray());
    }

    /// <summary>
    /// Not implemented
    /// </summary>
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }

#endregion
}

}


您不得将依赖项属性注册为附加属性,而应注册为常规依赖项属性。此外,你不应该使用new ObservableCollection<object>()作为默认属性值,因为这将使用相同的集合实例作为您的所有实例上的属性的默认值MultiSelectComboBox.

public static readonly DependencyProperty SelectedItemsProperty =
    DependencyProperty.Register( // Register instead of RegisterAttached
        "SelectedItems",
        typeof(ObservableCollection<object>), 
        typeof(MultiSelectComboBox), 
        new PropertyMetadata(SelectedItemsPropertyChanged)); // no default value

我也建议不要使用ObservableCollection<object>作为属性类型,但简单地说ICollection or IEnumerable反而。这将允许其他实现INotifyCollectionChanged在具体的集合类型中。

public static readonly DependencyProperty SelectedItemsProperty =
    DependencyProperty.Register(
        "SelectedItems",
        typeof(ICollection),
        typeof(MultiSelectComboBox),
        new PropertyMetadata(SelectedItemsPropertyChanged));

public ICollection SelectedItems
{
    get { return (ICollection)GetValue(SelectedItemsProperty); }
    set { SetValue(SelectedItemsProperty, value); }
}

private static void SelectedItemsPropertyChanged(
    DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    var comboBox = (MultiSelectComboBox)obj;
    var oldCollection = e.OldValue as INotifyCollectionChanged;
    var newCollection = e.NewValue as INotifyCollectionChanged;

    if (oldCollection != null)
    {
        oldCollection.CollectionChanged -= SelectedItemsCollectionChanged;
    }

    if (newCollection != null)
    {
        newCollection.CollectionChanged += SelectedItemsCollectionChanged;
    }
}

private static void SelectedItemsCollectionChanged(
    object sender, NotifyCollectionChangedEventArgs e)
{
    switch (e.Action)
    {
        ...
    }
}

另请注意,MultiSelectComboBox不需要实施INotifyPropertyChanged。仅当通知非依赖属性的属性更改时才需要这样做。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DependencyProperty 未在 NotifyCollectionChanged 事件上通知 UI 的相关文章

随机推荐

  • ARDUINO 常数有什么用?以前是22,现在是100

    我正在使用热电偶并下载了 MAX6675 库 我想知道以下几行中 ARDUINO 常量的值是做什么用的 if ARDUINO gt 100 lcd write byte 0 else lcd print 0 BYTE endif lcd p
  • 使用 Youtube v3 API 下载字幕

    在尝试使用 OAuth 2 0 授权下载视频 不归我所有 的字幕时 我收到 403 禁止错误 其中指出 与请求关联的权限不足以下载字幕轨道 该请求可能无法正确处理 已授权 或者视频订单可能未启用第三方为此字幕提供的内容 在进一步的研究中 我
  • Ninja 相当于 Make 的“从该目录向下构建”功能(使用 CMake)?

    使用CMake和Make构建项目时 可以执行make从构建树的子目录 即从包含顶级目录的目录下面的目录 Makefile and make将 据我所知 构建该目录下或该目录下的所有目标 这是因为 CMake 生成了一个Makefile对于每
  • 是否有用于指定属性“显示名称”的 .NET 属性?

    是否有一个属性允许您为类中的属性指定用户友好的名称 例如 假设我有以下课程 public class Position public string EmployeeName get set public ContactInfo Employ
  • 通过 Applescript 在 Xcode 4 中添加文件断点

    我正在尝试使用 AppleScript 将断点添加到当前 XCode 项目中选定的 m 文件 现在我陷入了困境 因为 AppleScript 在尝试添加文件断点时不断返回 缺失值 我当前的 AppleScript 看起来像这样 其中 PRO
  • 在 JavaScript 中构建“类”的现代方法是什么? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 如何构建一个 类 具有属性和方法 并在其上创建大量实例 The modern方法是使用class https developer mo
  • apache 上的多个 ssl 虚拟主机

    我想在 apache 上使用它们自己的 ssl 证书配置两个虚拟主机 apache 2 2 22 和 openssl 1 0 1 debian 7 6 我找了很多关于SNI的文章 但还是无法正确配置 这是我的配置 端口配置文件 NameVi
  • 如何在 pandas 中进行左外连接排除

    我有两个数据框 A 和 B 我想在 A 中获取它们 但不在 B 中 就像左上角正下方的数据框一样 数据框 A 有列 a b others B 有列 a b others 没有 NaN 值 我尝试了以下方法 1 dfm dfA merge d
  • ISO 8601 中的时间戳 - 最后 6 位数字 yyyy-MM-dd'T'HH:mm:ss。

    我的时间戳看起来像这样 2015 03 21T11 08 14 859831 2015 03 21T11 07 22 956087 我读了一篇关于 ISO 8601 的 Wiki 文章 https en wikipedia org wiki
  • pandas - 计算另一列中每个唯一值的 DataFrame 中值的出现次数

    假设我有一个数据帧 term score 0 this 0 1 that 1 2 the other 3 3 something 2 4 anything 1 5 the other 2 6 that 2 7 this 0 8 someth
  • MySQL按日期分组的累积和

    我知道有一些与此相关的帖子 但我的情况有点不同 我想在这方面获得一些帮助 我需要从数据库中提取一些数据 这些数据是每天交互的累积计数 目前这就是我所拥有的 SELECT e Date AS e date count e ID AS num
  • 如何将 dll 导入到在网络服务器上运行的 ASP.NET Web 应用程序中

    我在 VS 2010 中创建了一个 dll 我将其放入网络服务器上的 app code 文件夹中 然后我通过尝试使用来访问它imports GetWebPageData 如果这意味着什么的话 dll 位于 bin debug 下的 vs 项
  • 如何在Java中的不同类中使用相同的对象

    假设我有 3 个 java 类 A B 和 C 我需要创建一个在 A 和 B 中都使用的 C 类对象 但单独创建该对象的问题是类 c 的构造函数被调用了 2 次 但我希望构造函数只被调用一次 所以我想将A类中创建的对象使用到B类中 因此 创
  • 如何从 Web api 控制器返回文件?

    我正在使用 MVC 5 Web Api 控制器 我想返回一个文件 Route public HttpResponseMessage GetFile var statusCode HttpStatusCode OK FileStream fi
  • jQuery 倒计时有问题吗?函数serverSync:服务器时间

    serverSync serverTime函数从服务器返回值 但我检查了服务器和客户端时间是否相同 当我调用服务器与服务器同步时 它不会显示倒计时 帮我 function var shortly new Date var newTime n
  • SQL更新记录,每次从1开始递增值

    我使用单个插入语句将批量记录添加到表中 我希望为每个新批次分配递增的数字 但每次都从 1 开始 所以 如果我有 Batch Name IncementingValue 1 Joe 1 1 Pete 2 1 Andy 3 2 Sue 1 2
  • Scrapy好像没有做DFO

    我有一个网站 我的爬虫需要遵循一定的顺序 例如 在开始进行 a2 之前 它需要先进行 a1 b1 c1 等操作 a b 和 c 中的每一个都由不同的解析函数处理 并且相应的 url 在 Request 对象中创建并生成 下面粗略地说明了我正
  • 不允许的参数嵌套属性 -rails

    我正在尝试向 2 个表提交表单 但不知何故我收到了此语法错误unexpected n 在这条线上joins sources landslide id and found unpermitted parameter sources在滑坡参数中
  • 无法从 Sequel gem 连接 mysql

    当我尝试从 Sequel 连接到 MySQL 时 我收到这些错误 require rubygems require sequel DB Sequel connect adapter gt mysql user gt root host gt
  • DependencyProperty 未在 NotifyCollectionChanged 事件上通知 UI

    我正在使用一个自定义控件 该控件具有选定的项目依赖属性 我已将其连接到集合更改事件 但未通知 UI 并且 PropertyChanged 事件始终为空 通常我会说这是一个数据上下文问题 但我无法更改控件上的数据上下文 因为不会显示任何数据