Hierarchical DataGrid Binding - wpf

I've gone brain dead on this...
I have a class something like
public class STDMBaseItem
{
public int Id { get; set; }
public string Name { get; set; }
public string Details { get; set; }
public STDMItemCollection Items { get; set; }
private STDMBaseItem Parent { get; set; }
public string FullName
{
get
{
if (Parent == null)
return Name;
else
return Parent.FullName + "/" + Name;
}
}
public STDMBaseItem()
{
Items = new STDMItemCollection();
}
}
public class STDMItemCollection : ObservableCollection<STDMBaseItem> { }
I am able to display items in a tree view fine, that is not my issue... I want to display it in a data grid with the columns: Id, FullName, Details
Data might look something like (1 item in main collection and 1 item in child collection):
ID | Item Name | Item Details
-- +--------------------+-------------------------
1 | First Item | Some Details
2 | First Item/Child | Some more details
The collection is named Items and is of type STDMItemCollection which has sub-items named Items of type STDMItemCollection (the same type)...
It seems like the XAML part should be simple, but I can't seem to get it.

Related

Advanced NoSQL Query (RavenDB)

I'm trying to run a query that gets all of my references, but it isn't working.
What I have right now is
from UserGroups
where Id="ActionGroup"
select Accomplishments.ID, Accomplishments.Accomplish
But I need only the Accomplishments.Accomplish that belong in my other collection ActivityAccomplishments and these are nested in another object.
To be exact, I'm trying to figure out how to query the UserGroups collection and only look at the one with id="ActionGroup". After that I need all of the Accomplishments.Accomplish strings within the UserGroup list to be filtered out if they don't match a id in ActivityAccomplishment.
Basically, in the UserGroup I'm looking at it's List Accomplishments needs to filter out all strings within the Acc class that don't match an Id in ActivityAccomplishments. Can someone please help me.
Here are the classes I'm using.
public class UserGroups
{
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public List<Acc> Accomplishments { get; set; }
}
public class Acc
{
public string Id { get; set; }
public List<string> Accomplish { get; set; }
}
public class ActivityAccomplishments
{
public string Id { get; set; }
}
try this:
from UserGroups
where Id = "ActionGroup" AND Accomplishments[].Accomplish != "theIdYouDontWant"
select Accomplishments[].Accomplish as AccomplishStringsList
(not necessary to add the 'as AccomplishStringsList' - it is just a name for the results)

Current Row Wpf

I want to get the name I have in the DataGrid In Windows From
Code :
var PersonName = DataGridView.CurrentRow.Cells [1] .value.ToString ();
But in wpf, this method is not for DataGrid
That's not the WPF way. You need to work with the underlying collection that is the DataSource of your DataGrid and use the SelectedItem property.
You need to derive the value from the class that PersonName came from. For example, assume you have a Person class like this.
public class Person
{
public string PersonName { get; set; }
public string Address { get; set; }
public string Age { get; set; }
}
To get the PersonName from the current selected row, you could do something like this:
if (myDataGrid.SelectedItem != null)
{
var PersonName = ((Person)myDataGrid.SelectedItem).PersonName;
// ... now do something with the PersonName
}

WPF datagrid one column as Combobox add each row different list

I have datagrid wpf and one column is as combobox. For each row I need different item list.
I have this structure
public class DuplicateType:List<string>
{
public string d { get; set; }
}
public class StructurDatLegend : ObservableObject
{
public bool selected { get; set; }
public string VName { get; set; }
public View VLeg { get; set; }
public XYZ VPol { get; set; }
public DuplicateType DuplicateT { get; set; }
}
foreach (Tuple<View, XYZ> LegItem in duplicatesheet.Getlegendcollection(vs))
{
DuplicateType o = new DuplicateType();
o.Add("tee");
o.Add("fdvxvx");
Legend.Add(new StructurDatLegend { selected = false, VName = LegItem.Item1.Name, VLeg = LegItem.Item1, VPol = LegItem.Item2 , DuplicateT = o });
}
How can I load this data in xaml code? This code doesn't work
<DataGridComboBoxColumn Header =" Duplicate" Width="100" x:Name="DuplicateType" DisplayMemberPath="d" SelectedItemBinding="{Binding Path= DuplicateT}" SelectedValuePath="{Binding DuplicateT}" />
Sorry because my English. Did you set DataContext for datagrid? In your xaml code, you set DisplayMemberPath="d" but in behind code d not be set.

Blocks in Episerver

So I am trying to create my first block. The idea of this block is to get latest news from an api end point and then show it on different pages on the website.
What I have understood is this
Create a block type, something like this
public class NewsBlock : BlockData
{
[CultureSpecific]
[Display(
Name = "Heading",
Description = "Add a heading.",
GroupName = SystemTabNames.Content,
Order = 1)]
public virtual String Heading { get; set; }
}
Then I create a model for my Block
public class LatestNewsViewModel
{
public NewsBlock NewsBlock { get; private set; }
public IEnumerable<dynamic> LatestNews { get; set; }
public LatestNewsViewModel(NewsBlock latestNewsBlock, IEnumerable<dynamic> latestNews)
{
NewsBlock = latestNewsBlock;
LatestNews = latestNews;
}
}
Then I creata a block controller and in the index action I get data from my api and fill the block container data
Then I create a partial view and then from controller pass data into the view
Then from the dashboard I can add my block where ever I want on the site
Is this the way to do it? Or am I missing something?
That seem about correct. Please note there are many ways and opinions on how to get your data from the content model through the controller to the actual view. The example below is just the most simple scenario I can come up with.
public class NewsBlock : BlockData
{
[CultureSpecific]
[Display(
Name = "Heading",
Description = "Add a heading.",
GroupName = SystemTabNames.Content,
Order = 1)]
public virtual String Heading { get; set; }
}
The controller
public class NewsBlockController : BlockController<NewsBlock>
{
// GET: NewsBlock
public override ActionResult Index(NewsBlock currentBlock)
{
// apistuff
ApiModelWhatever returnFromApi = "whatever";
var model = new LatestNewsViewModel(currentBlock, returnFromApi);
return PartialView(model);
}
}
ViewModel
public class LatestNewsViewModel
{
public string Heading { get; private set; }
public ApiModelWhatever ReturnFromApi { get; private set; }
public LatestNewsViewModel(NewsBlock latestNewsBlock, ApiModelWhatever returnFromApi)
{
Heading = latestNewsBlock.Heading;
ReturnFromApi = returnFromApi;
}
}
View
#model LatestNewsViewModel
<h2>#Html.PropertyFor(model => model.Heading)</h2>

WPF DataGrid build from List<SomeInterface> using AutoGenerateColumns

I'm trying to load data to DataGrid from a generic list.
the relevant code:
XAML:
<Grid>
<DataGrid DataContext="{Binding Lines}"
ItemsSource="{Binding}"
AutoGenerateColumns="True">
</DataGrid>
</Grid>
C#:
public IList<IReportLine> Lines { get; set; }
public interface IReportLine {}
public class ReportLine : IReportLine
{
public string A { get; set; }
public string B { get; set; }
}
It seems that the columns are taken from the type IReportLine - so I'm getting an empty DataGrid.
Of course, if I'm changing IReportLine definition to:
public interface IReportLine
{
string A { get; set; }
string B { get; set; }
}
it works perfectly, but i can't do that because every class that implement IReportLine has different Properties.
What can I do in order to make the columns be generated from the dynamic type of IReportLine?
Or have any other idea to solve my problem?
Thanks!
EDIT:
The interface holding the Lines property and the class implementing the interface(one of many):
interface IReport
{
string Header { get; set; }
IList<IReportLine> Lines { get; set; }
}
public class Report : IReport
{
public string Header
{
get;
set;
}
public IList<IReportLine> Lines
{
get;
set;
}
}
The DataContext of the DataGrid is IReport object.
So I can't Change
public IList<IReportLine> Lines { get; set; }
to
public IList<ReportLine> Lines { get; set; }
Instead of defining members in interface, make the list to be more verbose. You gotta tell dataGrid at least some specific type so that it can look for properties in it.
Change
public IList<IReportLine> Lines { get; set; }
to
public IList<ReportLine> Lines { get; set; }
UPDATE
Like I mentioned above, if you want columns to be auto generated, you gotta supply some specific type.
Consider scenario where you have another class say AnotherReportLine implementing IReportLine:
public class AnotherReportLine : IReportLine
{
public string A { get; set; }
public string B { get; set; }
public string C { get; set; }
}
Now, you can add both class instances in Lines collection like this:
Lines = new List<IReportLine>();
Lines.Add(new ReportLine() { A = "A1", B = "B1" });
Lines.Add(new AnotherReportLine() { A = "A1", B = "B1", C = "C1" });
What should be the columns list now?
A | B OR A | B | C.
WPF engine cannot infer that without your help.
That brings you down to three possible ways:
Move properties to interface.
Make the list of more specific type.
Last set AutoGenerateColumns to False and provide your own list of columns you want to show.

Resources