TreeView Binding List<String> - treeview

I can't seem to figure out how to get the TreeView to display a List
I checked SO, but can't sem to find the same scenario the leafs always seem to be objects and not simple strings.
I can't figure out the correct combination of HierarchicalDataTemplate and DataTemplate to get it to work. Using the following Object. The binding happens I just only see the first level and not the leaves.
public class Trunk
{
public Trunk(string tn)
{
TrunkName = tn;
Branches = new List<Branch>();
}
public List<Branch> Branches { get; set; }
public string TrunkName { get; set; }
}
public class Branch
{
public Branch(string bn)
{
BranchName = bn;
Leaves = new List<string>();
}
public List<string> Leaves { get; set; }
public string BranchName { get; set; }
}
Tree = new Trunk("Root")
{
Branches =
{
new Branch("Branch1"){Leaves = {"Leaf1","Leaf2"}},
new Branch("Branch2"){Leaves = {"Leaf3","Leaf4"}}
}
};
And the following Template
<TreeView ItemsSource="{Binding Trees}" >
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Branches}">
<TextBlock Text="{Binding Path=TrunkName}" />
<HierarchicalDataTemplate.ItemTemplate >
<DataTemplate>
<TextBlock Text="{Binding BranchName}"/>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
EDIT:
Of course after spending days trying to figure out what wasn't clicking. I figured it out after posting for help.
PS the TreeView ItemsSource is set from the ViewModel bound to the Window DataContext.
<TreeView ItemsSource="{Binding Trees}" >
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Branches}">
<TextBlock Text="{Binding Path=TrunkName}" />
<HierarchicalDataTemplate.ItemTemplate >
<HierarchicalDataTemplate ItemsSource="{Binding Leaves}">
<TextBlock Text="{Binding BranchName}"/>
<HierarchicalDataTemplate.ItemTemplate >
<DataTemplate>
<TextBlock Text="{Binding }"/>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>

Related

CollectionView with ObservableRangeCollection not updating data change

I want to change the data of one object in my ObservableRangeCollection, and that works but the corresponding 'CollectionView` does not update the changed data.
'CollectionView`
<RefreshView Grid.Row="1"
Grid.RowSpan="2"
Command="{Binding RefreshCommand}"
IsRefreshing="{Binding IsBusy, Mode=OneWay}">
<CollectionView x:Name="Collection"
ItemsSource="{Binding Locations}"
SelectionMode="Single"
BackgroundColor="Transparent"
ItemsLayout="VerticalList">
<CollectionView.EmptyView>
<StackLayout Padding="12">
<Label HorizontalOptions="Center" Text="Keine Daten vorhanden!" TextColor="White"/>
</StackLayout>
</CollectionView.EmptyView>
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="models:MainModel">
<Frame HeightRequest="260">
<Grid>
<Image Source="{Binding Image}"
Aspect="AspectFill"/>
<Label Text="{Binding Name}"
FontSize="30"
TextColor="White"/>
</Grid>
</Frame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</RefreshView>
ViewModel
public class MainViewModel : VeiwModelBase
{
public ObservableRangeCollection<MainModel> Locations { get; set; } = new ObservableRangeCollection<MainModel>();
public ICommand RefreshCommand { get; }
public MainViewModel()
{
RefreshCommand = new AsyncCommand(Refresh);
}
public override void VModelActive(Page sender, EventArgs eventArgs)
{
base.VModelActive(sender, eventArgs);
var locs = new MainModel() { Image = "https://club-l1.de/wp-content/uploads/2019/11/dsc08645-1200x800.jpg", Name = "Test" };
Locations.Add(locs);
foreach (MainModel loc in Locations)
{
loc.Name = "Update";
}
}
private async Task Refresh()
{
IsBusy = true;
var locs = new MainModel() { Image = "https://club-l1.de/wp-content/uploads/2019/11/dsc08645-1200x800.jpg", Name = "Test"};
Locations.Add(locs);
foreach (MainModel loc in Locations)
{
loc.Name = "Update";
}
IsBusy = false;
}
}
The Project: https://github.com/Crey443/CollectionViewUpdate
MainModel needs to implement INotifyPropertyChanged, and any properties you want to bind (ie, Name) need to call PropertyChanged in their setters
public class MainModel
{
public string Name { get; set; }
public string Image { get; set; }
}

Properly binding list ItemsSource to Linq Table

I'm trying to bind a list box's items source to a Linq Table, the same way you would usually bind a ObservableCollection to it.
I want my list to update with the table when items are removed, added and changed.
I've implemented the INotifyPropertyChanged on the classes of which the table consists. This makes the list update the properties that my items contain, however, in order to update the list when items are added or removed, I have to programmatically rebind the ItemsSource in order to forcefully update the list.
Data context
public class LocalDatabase : DataContext
{
public static string connectionString = "Data Source=isostore:/Database.sdf";
public LocalDatabase() : base(connectionString) { }
public Table<Connection> Connections;
}
Table objects
[Table]
public class Connection : INotifyPropertyChanged
{
private string name;
private string ip;
private ushort port;
[Column(IsPrimaryKey=true, IsDbGenerated=true)]
public int ID { get; set; }
[Column]
public string Name { get { return name; } set { name = value; NotifyPropertyChanged("Name"); } }
[Column]
public string IP { get { return ip; } set { ip = value; NotifyPropertyChanged("IP"); } }
[Column]
public ushort Port { get { return port; } set { port = value; NotifyPropertyChanged("Port"); } }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Target list
<ListBox Name="listBoxConnections" SelectionChanged="listBoxConnections_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432" Height="78">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="Edit" Click="ConnectionEdit" Tag="{Binding ID}" />
<toolkit:MenuItem Header="Delete" Click="ConnectionDelete" Tag="{Binding ID}" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<TextBlock Text="{Binding Name}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<StackPanel Orientation="Horizontal" Margin="12,-6,12,0">
<TextBlock Text="{Binding IP}" Style="{StaticResource PhoneTextSubtleStyle}" Margin="0" />
<TextBlock Text=":" Margin="2,0,2,0" />
<TextBlock Text="{Binding Port}" Style="{StaticResource PhoneTextSubtleStyle}" Margin="0" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Current binding method
public LocalDatabase Database { get; set; }
public MainPage()
{
InitializeComponent();
Database = new LocalDatabase();
if (!Database.DatabaseExists()) Database.CreateDatabase();
listBoxConnections.ItemsSource = Database.Connections;
DataContext = this;
}
I'm afraid there might be a duplicate somewhere, but I've been searching for the last 2 days, and found no solution or similar question. Probably using the wrong queries.
So, in summary, I want to know the correct way to bind a Table to a list, with it updating upon item removal or addition, and all of that good stuff.
I'm working with Windows Phone 7.1
The best way is to separate your UI code from your DB code. Let your ListBox bind to an ObservableCollection, instead of a Table.
Try reading this:
http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj207023%28v=vs.105%29.aspx

DataBinding From Json in xaml?

I am making a WP7 app and getting data back from my webapi as json. I am wondering how can I databind it? Do I need to make a concrete class or can I just use JArray?
[{"Id":"fe480d76-deac-47dd-af03-d5fd524f4086","Name":"SunFlower Seeds","Brand":"PC"}]
JArray jsonObj = JArray.Parse(response.Content);
this.listBox.ItemsSource = jsonObj;
<ListBox x:Name="listBox" FontSize="26" Margin="0,67,0,0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Id}" Width="100"/>
<TextBlock Text="{Binding Brand}" Width="100"/>
<TextBlock Text="{Binding Name}" Width="100"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
When binding with WPF, you need to use Properties. Create a strongly typed object and then deserialize the JSON.
Create your object:
public class MyObject
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Brand { get; set; }
}
And here is a very loose example of binding based on how you've indicated you'll be setting the ItemsSource of the list box:
string json = "[{\"Id\":\"fe480d76-deac-47dd-af03-d5fd524f4086\",\"Name\":\"SunFlower Seeds\",\"Brand\":\"PC\"}]";
var jsonObj = JArray.Parse( json );
var myObjects = jsonObj.Select( x => JsonConvert.DeserializeObject<MyObject>( x.ToString() ) );
this.listBox.ItemsSource = myObjects;
Note: I've not used json.net, so there may be a better way to deserialize an array with json.net that what I've posted.

how to populate values to list box from a string array

I have a string array and i need to populate its value to a list box.but the values are not get in the list box. here is my code
xaml
'<ListBox Name="listBox_1" Background="White" Margin="3,131,0,0">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderThickness="0,1,0,0" BorderBrush="#FFC1BCBC" Width="480">
<Grid Height="80">
<TextBlock Name="list"
Text="{Binding Path=Names}"
FontSize="36"
TextWrapping="Wrap"
Foreground="Black" FontWeight="Normal"/>
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>'
class
'public class Names
{
//Model Class to hold Category details
public string Title { get; set; }
public string[] Names { get; set; }
public string[] Value { get; set; }
}'
xaml.cs
'protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
string[] name = ((Application.Current as App).obj_category.Names);
listBox_1.ItemsSource=name;
}'
i didnt get the names displayed in the list box.but i got the border lines that is, if the string contain 3 names i got three blank rows.why the text in it doesnot display?could any one help me .
DataContext in your ListBox is of type string[] and DataContext in each DataTemplate is a string which doesn't have a property Name.
Change Text="{Binding Path=Name}" to Text="{Binding}".

WP7/Silverlight How do you toggle a checkbox inside a list?

I'm having issues trying to figure this out. Basically, I have a listbox with a checkbox in it, making it a "Checked" listbox.
What I want to do is when a user hits a button, the checkbox is toggled (either shows or hides).
I've tried binding the visibility to a property in my view model but that isn't work.
What is the correct way to go about this? I've searched google and SO and couldn't find anything solid.
Thanks.
Bind visibility of the checkbox to a property of the class contained in the list that is the items source of the listbox.
Here is some code. This was a quick test and uses code behind but should be easily ported to your view model.
Class:
public class CheckString
{
public Visibility Visibility
{
get
{
Visibility retval = Visibility.Collapsed;
if (IsChecked)
{
retval = Visibility.Visible;
}
return retval;
}
}
public bool IsChecked { get; set; }
public string Description { get; set; }
public CheckString() {}
}
Code behind
public partial class MainPage : PhoneApplicationPage
{
public List<CheckString> CheckStringList { get; set; }
// Constructor
public MainPage()
{
InitializeComponent();
SetupList();
DataContext = this;
}
private void SetupList()
{
CheckStringList = new List<CheckString>();
CheckString cs1 = new CheckString { Description = "Test 1"};
CheckStringList.Add(cs1);
CheckString cs2 = new CheckString { IsChecked = true, Description = "Test 2" };
CheckStringList.Add(cs2);
CheckString cs3 = new CheckString { Description = "Test 3" };
CheckStringList.Add(cs3);
}
}
Xaml
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition
Width="Auto" />
<ColumnDefinition
Width="*" />
</Grid.ColumnDefinitions>
<CheckBox
Grid.Column="0"
Visibility="{Binding Visibility}"
IsChecked="{Binding IsChecked}" />
<TextBlock
Grid.Column="1"
Text="{Binding Description}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Resources