- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用一个自定义控件,它有一个选定的项目依赖属性,我已经连接了集合更改事件,但未通知 UI 并且 PropertyChanged 事件始终为 null。通常我会说这是一个数据上下文问题。但我无法更改控件上的数据上下文,因为不会显示任何数据。
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 中绑定(bind)到 ViewModel 上的 ObservableCollection 的属性声明。我错过了什么。该控件实现 INotifyPropertyChanged。
我在下面添加了更多代码。这是原始代码,我想将相同的属性更改为依赖属性以绑定(bind)到集合目的。
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
或 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
.这仅在通知非依赖属性的属性更改时才有必要。
关于c# - DependencyProperty 未在 NotifyCollectionChanged 事件上通知 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15886762/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!