XAML Data Binding to another Class - c#

What is the best way to bind Tag Attribute of ChildButton in TreeView(in the code Tag="{Binding ParentData}" to ParentData property of class TreeParent?
<TreeView>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:TreeParent}" ItemsSource="{Binding Members}">
<Button x:Name="ParentButton" Text="{Binding ParentName}">
</Button>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type local:TreeChild}" ItemsSource="{Binding Members}">
<Button x:Name="ChildButton" Text="{Binding ChildName}" Tag="{Binding ParentData}">
</Button>
</DataTemplate>
</TreeView.Resources>
</TreeView>
And the .cs code behind xaml file looks like this:
public class TreeParent
{
public string ParentName { get; set; }
public SomeDataClass ParentData { get; set; }
public ObservableCollection<TreeChild> Members { get; set; }
}
public class TreeChild
{
public string ChildName { get; set; }
}

Try this:
<Button x:Name="ChildButton" ...
Tag="{Binding DataContext.ParentData,
RelativeSource={RelativeSource AncestorType=TreeViewItem, AncestorLevel=2}}" />

Related

WPF Hierarchial Data Template differrent properties in classes

How to make tree where leaves would be different properties of the classes?
I want to get something like this
AMachine
-Wheels
Bmachine
-Years
Code.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new TestViewModel();
}
}
public class TestViewModel
{
public ObservableCollection<IBase> Items { get; set; }
public TestViewModel()
{
Items = new ObservableCollection<IBase>();
Items.Add(new AMachine { Wheels = "3", Name = "AMachine" });
Items.Add(new BMachine { Years = "2", Name = "BMachine" });
}
}
public interface IBase
{
}
public class AMachine : IBase
{
public string Name { get; set; }
public string Wheels { get; set; }
}
public class BMachine : IBase
{
public string Name { get; set; }
public string Years { get; set; }
}
Xaml.cs
<Grid>
<TreeView Height="300" Width="300" ItemsSource="{Binding Items}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type self:IBase}" ItemsSource="{Binding Items}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
You don't need hierarchical data template here, the logical would be to use normal data templates and ListBox (with expanders as nodes?):
<ListBox ItemsSource="{Binding Items}">
<ListBox.Resources>
<DataTemplate DataType="{x:Type local:AMachine}">
<Expander Header="{Binding Name}">
<TextBlock Text="{Binding Wheels}" />
</Expander>
</DataTemplate>
<DataTemplate DataType="{x:Type local:BMachine}">
<Expander Header="{Binding Name}">
<TextBlock Text="{Binding Years}" />
</Expander>
</DataTemplate>
</ListBox.Resources>
</ListBox>

How to organize ItemSource for such DataGrid

I'm Using MVVM and can't figure out how to organize ItemSource class for such DataGrid.
DataGrid XAMl code:
<DataGrid CanUserAddRows="True"
ItemsSource="{Binding TestCollection}">
<DataGrid.Columns>
<DataGridTemplateColumn Header="First Column">
<DataGridTemplateColumn.CellEditingTemplate >
<DataTemplate >
<ContentControl>
<StackPanel>
<TextBox Text="{Binding First}"/>
<TextBox Text="{Binding Second}"/>
</StackPanel>
</ContentControl>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Second Column">
<DataGridTemplateColumn.CellEditingTemplate >
<DataTemplate >
<ContentControl>
<StackPanel>
<TextBox Text="{Binding Third}"/>
<TextBox Text="{Binding Fourth}"/>
</StackPanel>
</ContentControl>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
I have this idea, but it doesn't work.
public class ComplexTable
{
public ComplexTable()
{
FirstProperty = new FirstClass();
SecondProperty = new Second();
}
public class FirstClass
{
public FirstClass()
{
First = "FirstString";
Second = "SecondString";
}
public string First { get; set; }
public string Second { get; set; }
}
public class Second
{
public Second()
{
Third = "ThirdString";
Fourth = "FourthString";
}
public string Third { get; set; }
public string Fourth { get; set; }
}
public FirstClass FirstProperty { get; set; }
public Second SecondProperty { get; set; }
}
public ObservableCollection<ComplexTable> _testCollection = new ObservableCollection<ComplexTable>();
private ObservableCollection<ComplexTable> TestCollection
{
get { return _testCollection; }
set
{
_testCollection = value;
RaisePropertyChanged("TestCollection");
}
}
As i understand each property in class for ItemSource responsible for column in DataGrid, and if cell contains several controls etc. property Type should consist property for each control as well. Cant figure out where am i wrong.
http://www.codeproject.com/Articles/683429/Guide-to-WPF-DataGrid-formatting-using-bindings
You can understand with this link.
<StackPanel>
<TextBox Text="{Binding SelectedItem.Name, ElementName=myDataGrid}"/>
<DataGrid x:Name="myDataGrid" />
</StackPanel>

Binding nested JSON to listbox in XAML

This is my modal,
public class main
{
public List<categories> categorieslist { get; set; }
}
public class categories
{
public int categoryId { get; set; }
public string categoryName { get; set; }
public List<pdf> pdfdocs { get; set; }
public List<video> videoFiles { get; set; }
}
public class pdf
{
public string URL { get; set; }
public string language { get; set; }
public string createdDate { get; set; }
public bool isFavorite { get; set; }
public bool isRead { get; set; }
}
Im using JSON.NET to deserialize
main mainobj = JsonConvert.DeserializeObject<main>(App.hello);
I need to display list of PDF's for a selected category,
Im using LINQ to filter that particular category, I am unable to bind the PDF list..
pdf.ItemsSource = App.mainobj.categorieslist.Where(i => i.categoryId.Equals(s));
<ListBox x:Name="pdf" Margin="0,0,0,363" ItemsSource="{Binding}" Foreground="White">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding pdf.URL}" Foreground="White"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox ItemsSource="{Binding categorieslist}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding categoryId }" FontSize="20" />
<ItemsControl ItemsSource="{Binding pdf}" Margin="0 20 0 0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Blue" BorderThickness="2">
<TextBlock Text="{Binding URL }" FontSize="20" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl ItemsSource="{Binding videoFiles}" Margin="0 20 0 0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Red" BorderThickness="2">
<TextBlock Text="{Binding URL}" FontSize="20" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>

DataBinding a 2nd degree subclass

I need help in binding data especially if the root datasource object has many subclasses and those subclasses has a subclass too. Here is my DataModel:
public class NowShowingMovies
{
public ObservableCollection<Movie> MovieCollection { get; set; }
public string Status { get; set; }
public string Total{ get; set; }
}
public class Movie
{
public string Id {get;set;}
public string Title {get;set}
public UserRating Rating {get;set;}
}
public class UserRating
{
public string UserRatingURL {get;set;}
}
And my XAML code is:
<GridView ItemsSource="{Binding MovieCollection}"
<GridView.ItemTemplate>
<DataTemplate>
<Grid>
<Border Background="White">
<TexBlock Text="{Binding Title}"/>
</Border>
<Grid Background="Black" Margin="0,0,0,0" Opacity="0.75" x:Name="grid_rating"/>
<Image Source ="{Binding Path=MovieCollection.Rating.UserRatingURL}" />
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
Problem is I can't make it work. UserRatingURL is not showing. I even changed it to
<Image Source ="{Binding Path=MovieCollection[0].Rating.UserRatingURL}" />
and still, no luck. What am I doing wrong? Thanks in advance!
Try to remove MovieCollection in your path.
Image Source ="{Binding Path=Rating.UserRatingURL}"

Get Object properties of selected list item

I have a listbox that has a listsource that is a list of 'results' objects. The results class looks like this:
public class Result
{
public string GUID { get; set; }
public string __invalid_name__I { get; set; }
public string FN { get; set; }
public string DOB { get; set; }
public string SEX { get; set; }
public string SN { get; set; }
public string __invalid_name__U { get; set; }
public string TYPE { get; set; }
//Gender icon path associated with result
public string SexIcon { get; set; }
}
And this is what my listbox looks like in the xaml code:
<ListBox
Height="517"
HorizontalAlignment="Left"
Margin="12,84,0,0"
Name="searchList"
VerticalAlignment="Top"
Width="438"
SelectionChanged="SearchList_SelectedEvent">
<!-- What each listbox item will look like -->
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Path=Sex, Converter={StaticResource SexToSourceConverter}}" Visibility="Visible" />
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Name="FirstName" Text="{Binding FN}" FontSize="28" Margin="0,0,10,0"/>
<TextBlock Name="LastName" Text="{Binding SN}" FontSize="28" />
</StackPanel>
<TextBlock Text="{Binding DOB}" FontSize="24" />
<!-- Line Stroke="#FF04863C" StrokeThickness="3" X1="100" Y1="100" X2="300" Y2="100" / -->
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
So my question is, (and what I'm really struggling with) is how does one for instance get the value of the GUID property of the selected Item (which is basically a results object)?
(searchList.SelectedItem as Result).GUID

Categories