Reputation: 1240
I wanted to avoid scrolling ListView
's Header
, so I've created custom controll for List, which consists of grid with two rows (first of them is header and in second I could place the ListView
, but I've successfully binded header with controll, but I can't do the same with data.
My ListViewCustomControl
class:
public sealed class ListViewCustomControl : Control
{
public static readonly DependencyProperty HeaderProperty =
DependencyProperty.Register(
"Header", typeof(string), typeof(ListViewCustomControl),
new PropertyMetadata("custom_template_row1"));
public static readonly DependencyProperty ElementsSourceProperty =
DependencyProperty.Register(
"ElementsSource", typeof(IObservable<Type>), typeof(ListViewCustomControl),
null);
public ListViewCustomControl()
{
DefaultStyleKey = typeof(ListViewCustomControl);
}
public string Header
{
get { return (string)GetValue(HeaderProperty); }
set { SetValue(HeaderProperty, value); }
}
public IObservable<Type> ElementsSource
{
get { return (IObservable<Type>)GetValue(ElementsSourceProperty); }
set { SetValue(ElementsSourceProperty, value); }
}
}
Style for my control:
<Style TargetType="local:ListViewCustomControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:ListViewCustomControl">
<Grid Background="BlueViolet">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Text="{TemplateBinding Header}"></TextBlock>
<ListView Grid.Row="1"
ItemsSource="{TemplateBinding ElementsSource}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding TypeVar}"></TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Sample of using in xaml file:
<local:ListViewCustomControl
Header="yolo" ElementsSource="{Binding data}">
</local:ListViewCustomControl>
sent data and Type
definition
private void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
var data = new List<Type>();
for (var i = 0; i < 123; i++) data.Add(new Type(i));
defaultViewModel["data"] = data;
}
public class Type
{
public int TypeVar { get; set; }
public Type(int i)
{
TypeVar = i;
}
}
As I've mentioned on the beginning. Header property works well, but I can't make data binding working well too...
update
I've noticed in debugger that SetValue
function from XamlTypeInfo.g.cs
has been invoked once, only to set Header
value.
update
I've changed IObservable
to IList
and what's more important default value of ElementsSourceProperty
and it works for default value, but I still can't change this value...
public static readonly DependencyProperty ElementsSourceProperty =
DependencyProperty.Register(
"ElementsSource", typeof(IList<Type>), typeof(ListViewCustomControl),
new PropertyMetadata(
new List<Type>(3)
{
new Type(4), new Type(5), new Type(6)
}));
Upvotes: 1
Views: 132
Reputation: 22702
Try change type of ElementsSource
:
IObservable<>
to:
IList<>
like this:
public static readonly DependencyProperty ElementsSourceProperty =
DependencyProperty.Register(
"ElementsSource", typeof(IList<Type>), typeof(ListViewCustomControl),
null);
public IList<Type> ElementsSource
{
get { return (IList<Type>)GetValue(ElementsSourceProperty); }
set { SetValue(ElementsSourceProperty, value); }
}
For test, try set for ListView
name and write this line in code-behind:
MyListView.ElementsSource = data;
Version with Binding
In this case, you must specify the DataContext
, which would you want us to list:
XAML
<local:ListViewCustomControl Header="yolo"
ElementsSource="{Binding TestList}" />
Code-behind
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var testData = new TestData();
testData.TestList = new List<Type>();
for (var i = 0; i < 123; i++)
testData.TestList.Add(new Type(i));
this.DataContext = testData;
}
}
public class TestData
{
public List<Type> TestList
{
get;
set;
}
}
Some notes
You can choose the type of IEnumerable
, because it is the base class for all collections.
When you create a dependency property you can skip PropertyMetadata
, in this case, the system will automatically assign a default value for this type.
Upvotes: 2