Skip to content

Instantly share code, notes, and snippets.

@ekhart
Last active June 22, 2021 20:52
Show Gist options
  • Save ekhart/c7519724b19af699f2f7ba6995cbc4f0 to your computer and use it in GitHub Desktop.
Save ekhart/c7519724b19af699f2f7ba6995cbc4f0 to your computer and use it in GitHub Desktop.
namespace Project.Views
{
// nasza klasa musi dziedziczyć po VisualElement, abyśmy mogli jej używać
public class CharacterElement : VisualElement
{
// elementy widoku (podwidoki) np. Button, Label, Text itd.
private Button closeButton;
private Label mainLabel;
private ListView optionViews;
// eventy
public event Action Initialized;
// konstruktor rejestruje się do eventu GeometryChangedEvent
public CharacterElement() =>
RegisterCallback<GeometryChangedEvent>(Initialize);
// dopiero w tym momencie mamy zainicjalizowany widok
private void Initialize(GeometryChangedEvent _)
{
// odrejestrowujemy się od eventu
UnregisterCallback<GeometryChangedEvent>(Initialize);
// za pomocą this.Q<typ> znajdujemy elementy widoku zdefiniowane w pliku .uxml
closeButton = this.Q<Button>("close-button"); // musimy użyć this, bo Q() to extension method
nameText = this.Q<TextField>("name-text");
healthSlider = this.Q<SliderInt>("health-slider");
optionViews = this.Q<ListView>(); // wyszukuje pierwszy element tego typu
// event, że widok jest poprawnie zainicjalizowany
Initialized?.Invoke();
}
public void Render(DialogNodeModel model) // korzystamy z podejścia MVC
{
// aby lista działała poprawnie musimy ustawić
// itemsSource - listę z danymi, które chcemy wyświetlać
optionViews.itemsSource = model.Options.ToList();
// funkcja zwracająca VisualElement tj. element listy
optionViews.makeItem = () => new Button();
// funkcja bindująca elementowi listy odpowiednie dane
optionViews.bindItem = BindOptionButton;
// funkcja lokalna mająca dostęp do argumenty model
void BindOptionButton(VisualElement element, int i)
{
var option = model.Options[i];
if (element is Button button) // castujemy element używając pattern matchingu
{
button.text = $"{i + 1}. {option.Text}";
button.clicked += () => OptionClicked?.Invoke(option);
}
}
}
// factory design pattern - abyśmy mogli używać nasz customowy element w .uxml oraz UI Builderze
// tj. <Project.Views.CharacterElement>...</Project.Views.CharacterElement>
private class Factory : UxmlFactory<CharacterElement>
{
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment