Элементы управления Dev Express предназначены для богатых людей, мы, бедняки, можем реализовать свои собственные!
Вам нужно будет создать элемент управления CardsPanel
с коллекцией CardViewModel
. Очевидно, что он прочитает каждый элемент коллекции, создаст для него элемент управления Card
, установит его модель представления и добавит в Panel
. Вы в принципе сами ответили на свой вопрос!
Что касается приятного плавного движения внутри этого CardControl, может потребоваться некоторый код для добавления Lerp и Slerp, но это не должно быть слишком сложно. Вы можете отслеживать пополнения коллекции с помощью ObservableCollection
, когда это необходимо. По вашей ссылке дизайн кажется очень простым, и его не составит труда подражать обычным Winforms.
Вот полный пример:
public class CardsPanel : Panel
{
const int CardWidth = 200;
const int CardHeight = 150;
public CardsViewModel ViewModel { get; set; }
public CardsPanel()
{
}
public CardsPanel(CardsViewModel viewModel)
{
ViewModel = viewModel;
ViewModel.Cards.CollectionChanged += Cards_CollectionChanged;
}
private void Cards_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
DataBind();
}
public void DataBind()
{
SuspendLayout();
Controls.Clear();
for(int i = 0; i < ViewModel.Cards.Count; i++)
{
var newCtl = new CardControl(ViewModel.Cards[i]);
newCtl.DataBind();
SetCardControlLayout(newCtl, i);
Controls.Add(newCtl);
}
ResumeLayout();
}
void SetCardControlLayout(CardControl ctl, int atIndex)
{
ctl.Width = CardWidth;
ctl.Height = CardHeight;
//calc visible column count
int columnCount = Width / CardWidth;
//calc the x index and y index.
int xPos = (atIndex % columnCount) * CardWidth;
int yPos = (atIndex / columnCount) * CardHeight;
ctl.Location = new Point(xPos, yPos);
}
}
public partial class CardControl : UserControl
{
public CardViewModel ViewModel { get; set; }
public CardControl()
{
InitializeComponent();
}
public CardControl(CardViewModel viewModel)
{
ViewModel = viewModel;
InitializeComponent();
}
public void DataBind()
{
SuspendLayout();
tbAge.Text = ViewModel.Age.ToString();
tbAge.Name = ViewModel.Name;
pbPicture.Image = ViewModel.Picture;
ResumeLayout();
}
}
public class CardsViewModel
{
public ObservableCollection<CardViewModel> Cards { get; set; }
}
public class CardViewModel
{
public string Name { get; set; }
public int Age { get; set; }
public Bitmap Picture { get; set; }
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
cardsPanel1.ViewModel = LoadSomeData();
cardsPanel1.DataBind();
}
private CardsViewModel LoadSomeData()
{
ObservableCollection<CardViewModel> cards = new ObservableCollection<CardViewModel>();
cards.Add(new CardViewModel()
{
Age = 1,
Name = "Dan",
Picture = new Bitmap(Image.FromFile("C:\\Users\\daniel.rayson\\Pictures\\CuteKitten1.jpg"))
});
cards.Add(new CardViewModel()
{
Age = 2,
Name = "Gill",
Picture = new Bitmap(Image.FromFile("C:\\Users\\daniel.rayson\\Pictures\\CuteKitten1.jpg"))
});
cards.Add(new CardViewModel()
{
Age = 3,
Name = "Glyn",
Picture = new Bitmap(Image.FromFile("C:\\Users\\daniel.rayson\\Pictures\\CuteKitten1.jpg"))
});
cards.Add(new CardViewModel()
{
Age = 4,
Name = "Lorna",
Picture = new Bitmap(Image.FromFile("C:\\Users\\daniel.rayson\\Pictures\\CuteKitten1.jpg"))
});
cards.Add(new CardViewModel()
{
Age = 5,
Name = "Holly",
Picture = new Bitmap(Image.FromFile("C:\\Users\\daniel.rayson\\Pictures\\CuteKitten1.jpg"))
});
CardsViewModel VM = new CardsViewModel()
{
Cards = cards
};
return VM;
}
}
Вы можете видеть здесь, что я вставил туда некоторые данные тестирования, но общие концепции уже есть, и это основа, с которой вы можете спрыгнуть.
Удачи!
person
Dan Rayson
schedule
10.07.2017