ListView of CheckBox with content binding
Hi,
I am trying to create a ListView of checkbox items, with data binding to a data model created in c++, but unable to make the checkbox items display. Not sure if there is anything I missed?
I referenced the tutorial here.
The XAML code is as follows:
C++ code:
NotifyPropertyChangedBase.h
at NoesisGUI/Source/Noesis/NoesisSDK/Src/Packages/App/ApplicationLauncher/Include/NsApp/NotifyPropertyChangedBase.h
NotifyPropertyChangedBase.cpp
at NoesisGUI/Source/Noesis/NoesisSDK/Src/Packages/App/ApplicationLauncher/Src/NotifyPropertyChangedBase.cpp
CustomDataModel.h
CustomDataModel.cpp
CheckBoxListControl.h,.cpp
Any pointer is appreciated, thanks!
I am trying to create a ListView of checkbox items, with data binding to a data model created in c++, but unable to make the checkbox items display. Not sure if there is anything I missed?
I referenced the tutorial here.
The XAML code is as follows:
Code: Select all
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:noesis="clr-namespace:NoesisGUIExtensions;assembly=Noesis.GUI.Extensions"
x:Class="FCheckBoxLisControl"
x:Name="CheckBoxListElement">
<UserControl.Resources>
<Style x:Key="CheckBoxListHeaderStyle" TargetType="GridViewColumnHeader">
<Setter Property="Background" Value="Cyan"/>
<Setter Property="Foreground" Value="Navy"/>
<Setter Property="Visibility" Value="Collapsed"/>
</Style>
<DataTemplate x:Key="CheckBoxListHeaderTemplate" DataType="GridViewColumnHeader">
<TextBlock Text="{Binding Header}"/>
</DataTemplate>
<DataTemplate x:Key="CheckBoxListCellTemplate">
<CheckBox Margin="0,5,0,0"
Content="{Binding Name}"/>
</DataTemplate>
<DataTemplate x:Key="CheckBoxItemTemplate">
<TextBlock Text="{Binding Name}">
<TextBlock.ToolTip>
<ToolTip Visibility="Collapsed">
<TextBlock Text="{Binding Description}"/>
</ToolTip>
</TextBlock.ToolTip>
</TextBlock>
</DataTemplate>
</UserControl.Resources>
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
<ListView x:Name="CheckBoxList"
SelectionMode="Multiple"
ItemsSource="{Binding ItemList}"
ItemTemplate="{StaticResource CheckBoxItemTemplate}">
<ListView.View>
<GridView>
<GridViewColumn HeaderTemplate="{StaticResource CheckBoxListHeaderTemplate}"
HeaderContainerStyle="{StaticResource CheckBoxListHeaderStyle}"
CellTemplate="{StaticResource CheckBoxListCellTemplate}"/>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
</UserControl>
NotifyPropertyChangedBase.h
at NoesisGUI/Source/Noesis/NoesisSDK/Src/Packages/App/ApplicationLauncher/Include/NsApp/NotifyPropertyChangedBase.h
NotifyPropertyChangedBase.cpp
at NoesisGUI/Source/Noesis/NoesisSDK/Src/Packages/App/ApplicationLauncher/Src/NotifyPropertyChangedBase.cpp
CustomDataModel.h
Code: Select all
class FCustomDataItem : public Noesis::BaseComponent
{
public:
FCustomDataItem(const char* InName, Noesis::ResourceDictionary* InDescription) : Name(InName), Description(InDescription)
{
}
const char* GetName() const
{
return Name.Str();
}
Noesis::ResourceDictionary* GetDescription() const
{
return Description;
}
private:
Noesis::String Name;
Noesis::Ptr<Noesis::ResourceDictionary> Description;
NS_DECLARE_REFLECTION(FCustomDataItem, Noesis::BaseComponent)
};
class FCustomDataModel : public NotifyPropertyChangedBase
{
public:
FCustomDataModel();
Noesis::ObservableCollection<FCustomDataItem>* GetItemList() const
{
return ItemList.GetPtr();
}
void AddItem(Noesis::Ptr<FCustomDataItem> InItem)
{
ItemList->Add(InItem);
}
void RemoveItem(Noesis::Ptr<FCustomDataItem> InItem)
{
ItemList->Remove(InItem);
}
void Reset()
{
Noesis::DynamicCast<Noesis::BaseCollection*>(GetItemList())->Clear();
}
int Num() const
{
return ItemList->Count();
}
void SetCurrentItem(FCustomDataItem* InItem);
FCustomDataItem* GetCurrentItem() const
{
return CurrentItem;
}
void SetCurrentIndex(uint32_t InItemIndex);
private:
Noesis::Ptr<Noesis::ObservableCollection<FCustomDataItem>> ItemList;
FCustomDataItem* CurrentItem = nullptr;
NS_DECLARE_REFLECTION(FCustomDataModel, FNotifyPropertyChangedBase)
};
Code: Select all
FCustomDataModel::FCustomDataModel()
{
ItemList = Noesis::MakePtr<Noesis::ObservableCollection<FCustomDataItem>>();
TArray<FString> itemContentList = { "A", "B" };
for (const auto& itemContent : itemContentList)
{
ItemList->Add(Noesis::MakePtr<FCustomDataItem>(TCHAR_TO_UTF8(*itemContent), nullptr));
}
SetCurrentIndex(0);
}
void FCustomDataModel::SetCurrentItem(FCustomDataItem* InItem)
{
if (CurrentItem != InItem)
{
CurrentItem = InItem;
OnPropertyChanged("CurrentItem");
}
}
void FCustomDataModel::SetCurrentIndex(uint32_t InItemIndex)
{
SetCurrentItem(ItemList->Get(InItemIndex));
}
NS_BEGIN_COLD_REGION
NS_IMPLEMENT_REFLECTION(FCustomDataItem)
{
NsProp("Name", &FCustomDataItem::GetName);
NsProp("Description", &FCustomDataItem::GetDescription);
}
NS_IMPLEMENT_REFLECTION(FCustomDataModel)
{
NsProp("ItemList", &FCustomDataModel::GetItemList);
NsProp("CurrentItem", &FCustomDataModel::GetCurrentItem, &FCustomDataModel::SetCurrentItem);
}
Code: Select all
class FCheckBoxListControl : public Noesis::UserControl
{
public:
FCheckBoxListControl()
{
XAMLDataModel = Noesis::MakePtr<FCustomDataModel>();
Noesis::FrameworkElement::SetDataContext(XAMLDataModel);
}
Noesis::Ptr<FCustomDataModel> GetXAMLDataModel() const override final
{
return XAMLDataModel;
}
protected:
Noesis::Ptr<FCustomDataModel> XAMLDataModel = nullptr;
private:
NS_DECLARE_REFLECTION(FCheckBoxListControl, Noesis::UserControl)
};
NS_BEGIN_COLD_REGION
NS_IMPLEMENT_REFLECTION(FCheckBoxListControl, "FCheckBoxListControl")
{
}
-
sfernandez
Site Admin
- Posts: 2991
- Joined:
Re: ListView of CheckBox with content binding
Are you including this FCheckBoxListControl as part of another xaml?
As described in the Unreal tutorial, you need to specify the xaml that should be loaded (LoadComponent) when constructing the user control, otherwise it will create a simple control with no content. And you should specify a namespace for the control name, so it can be correctly mapped in Blend and xaml. Finally you will need to register the component in your module so it can be created by the xaml parser.
I tried your code with the changes I mentioned and I was able to see the list with the check boxes. Could you confirm if that was your problem?
As described in the Unreal tutorial, you need to specify the xaml that should be loaded (LoadComponent) when constructing the user control, otherwise it will create a simple control with no content. And you should specify a namespace for the control name, so it can be correctly mapped in Blend and xaml. Finally you will need to register the component in your module so it can be created by the xaml parser.
I tried your code with the changes I mentioned and I was able to see the list with the check boxes. Could you confirm if that was your problem?
Who is online
Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot] and 25 guests