Еще одно решение, похожее на Ray, но вместо медленного и громоздкого копирования пикселей, это использует некоторые внутренние элементы Windows:
private struct IconInfo {
public bool fIcon;
public int xHotspot;
public int yHotspot;
public IntPtr hbmMask;
public IntPtr hbmColor;
}
[DllImport("user32.dll")]
private static extern IntPtr CreateIconIndirect(ref IconInfo icon);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);
public Cursor ConvertToCursor(FrameworkElement cursor, Point HotSpot) {
cursor.Arrange(new Rect(new Size(cursor.Width, cursor.Height)));
var bitmap = new RenderTargetBitmap((int)cursor.Width, (int)cursor.Height, 96, 96, PixelFormats.Pbgra32);
bitmap.Render(cursor);
var info = new IconInfo();
GetIconInfo(bitmap.ToBitmap().GetHicon(), ref info);
info.fIcon = false;
info.xHotspot = (byte)(HotSpot.X * cursor.Width);
info.yHotspot = (byte)(HotSpot.Y * cursor.Height);
return CursorInteropHelper.Create(new SafeFileHandle(CreateIconIndirect(ref info), true));
}
В середине есть метод расширения, который я предпочитаю иметь в класс расширения для таких случаев:
using DW = System.Drawing;
public static DW.Bitmap ToBitmap(this BitmapSource bitmapSource) {
var bitmap = new DW.Bitmap(bitmapSource.PixelWidth, bitmapSource.PixelHeight, DW.Imaging.PixelFormat.Format32bppPArgb);
var data = bitmap.LockBits(new DW.Rectangle(DW.Point.Empty, bitmap.Size), DW.Imaging.ImageLockMode.WriteOnly, DW.Imaging.PixelFormat.Format32bppPArgb);
bitmapSource.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
bitmap.UnlockBits(data);
return bitmap;
}
При этом все довольно просто и просто.
И если вам не нужно указывать свою собственную точку доступа, вы можете даже сократите это сокращение (вам не нужна структура или P / Invokes):
public Cursor ConvertToCursor(FrameworkElement cursor, Point HotSpot) {
cursor.Arrange(new Rect(new Size(cursor.Width, cursor.Height)));
var bitmap = new RenderTargetBitmap((int)cursor.Width, (int)cursor.Height, 96, 96, PixelFormats.Pbgra32);
bitmap.Render(cursor);
var icon = System.Drawing.Icon.FromHandle(bitmap.ToBitmap().GetHicon());
return CursorInteropHelper.Create(new SafeFileHandle(icon.Handle, true));
}
@Rahul проверьте следующий код:
class Movie : NSObject {
var imageName: String!
var selected: Bool!
}
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableview: UITableView!
var headerLabel:String!
var ListmoviesArray:[Movie]!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Add your data of type Movie here
ListmoviesArray = [ ]
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return ListmoviesArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.tableview.dequeueReusableCell(withIdentifier: "ListTableViewCell", for: indexPath) as! ListTableViewCell
cell.imageView?.image = UIImage(named: ListmoviesArray[indexPath.row].imageName)
cell.btnCheckMark.addTarget(self, action: #selector(checkMarkButtonClicked), for: .touchUpInside)
cell.btnCheckMark.tag = indexPath.row
cell.btnCheckMark.setImage(UIImage(named: ListmoviesArray[indexPath.row].selected ? "Checked" : "UnChecked"), for: .normal)
cell.selectionStyle = .none
return cell
}
@objc func checkMarkButtonClicked ( sender: UIButton) {
sender.isSelected = !sender.isSelected
ListmoviesArray[sender.tag].selected = sender.isSelected
if sender.isSelected {
sender.setImage(UIImage(named: "Checked"), for: .normal)
} else {
sender.setImage(UIImage(named: "UnChecked"), for: .normal)
}
}
@IBAction func deleteButtonTapped(_ sender: UIButton) {
for selectedItem in ListmoviesArray {
if (selectedItem.selected == true) {
ListmoviesArray.remove(at: sender.tag)
}
}
tableview.reloadData()
}
}
Элегантный способ решения этой проблемы - использование Делегирования. Я дам вам пример того, как вы можете решить эту проблему.
Прежде всего в протоколе TableViewCell Объявление:
protocol MovieTableViewCellDelegate : class {
func movieSelection(_ movie : Movie,indexPath: IndexPath)
}
Добавьте следующий метод в ваш класс TableViewCell
func setupCell(_ movie : Movie, indexPath: IndexPath) {
self.indexPath = indexPath
self.selectedMovie = movie
movieLabel.text = movie.name
// This is just to show you selected movie
// let image : UIImage = movie.isSelected ? #imageLiteral(resourceName: "checkBoxSelected") : #imageLiteral(resourceName: "checkBoxUnselected")
// checkBoxButton.setImage(image, for: .normal)
}
[ 1114] Получите IBAction кнопки, которую вы хотите использовать для удаления фильма:
@IBAction func checkBoxButtonAction(_ sender: Any) {
delegate.movieSelection(selectedMovie, indexPath: indexPath)
}
Реализация метода TableView Delegate и DataSource должна выглядеть следующим образом:
extension ViewController : UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return listmoviesArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MovieTableViewCell", for: indexPath) as! MovieTableViewCell
cell.delegate = self
cell.setupCell(listmoviesArray[indexPath.row],indexPath: indexPath)
return cell
}
}
Делегировать реализацию для удаления фильма из списка:
extension ViewController : MovieTableViewCellDelegate {
func movieSelection(_ movie: Movie,indexPath: IndexPath) {
// Write your code here to delete movie
listmoviesArray.remove(at: indexPath.row)
moviesTableView.reloadData()
}
}