I have the following xaml file:
<Page ...>
<Grid>
<ListView ItemsSource="{Binding MissingValues}">
<ListView.View>
<GridView AllowsColumnReorder="true" ColumnHeaderToolTip="Information on Missing Values">
<GridViewColumn DisplayMemberBinding="{Binding Path=Element.Name}" Header="Element" Width="100" />
<GridViewColumn DisplayMemberBinding="{Binding Path=Description}" Header="Description" />
</GridView>
</ListView.View>
</ListView>
</Grid>
Code behind is only:
DataContext = new MyViewModel();
And MyViewModel has public ObservableCollection<MissingValue> MissingValues initialized in the constructor. On the button click, items are added to this property and everything works as exptected.
Since the xaml file became too big, i wanted to make it smaller and easier to manage by extracting this ListView in a UserControl called MissingValuesListView and invoking it using the following code:
<local:MissingValuesListView></local:MissingValuesListView>
However, the list is no longer updated when the new elements are added.
MissingValuesListView's code behind contains only DataContext = new MyViewModel();.
I don't think it's of any relevance (since the code works when part of the main xaml file, but not when moved to UserControl), but both MyViewModel and MissingValue implment INotifyPropertyChanged.
My question is why is this not working? I assume i'm missing some code or some binding, but i failed to find out what. Any help is highly appreciated!
MissingValuesListView's code behind contains only DataContext = new MyViewModel();.
It shouldn't. Try to remove this line. You should simply copy the following XAML into MissingValuesListView.xaml and replace it with <local:MissingValuesListView /> in the current XAML file:
<ListView ItemsSource="{Binding MissingValues}">
<ListView.View>
<GridView AllowsColumnReorder="true" ColumnHeaderToolTip="Information on Missing Values">
<GridViewColumn DisplayMemberBinding="{Binding Path=Element.Name}" Header="Element" Width="100" />
<GridViewColumn DisplayMemberBinding="{Binding Path=Description}" Header="Description" />
</GridView>
</ListView.View>
</ListView>
If you do this, the UserControl will inherit the DataContext where the MissingValues property is defined from its parent element and the binding should work just like before.
Related
Firstly:
<ListView Height="259" HorizontalAlignment="Left" Margin="7,6,0,0" Name="dataListView" VerticalAlignment="Top" Width="899">
<ListView.View>
<GridView>
<GridViewColumn Width="240" Header="Test" />
<GridViewColumn Width="50" Header="Result" />
<GridViewColumn Header="Column 3" />
</GridView>
</ListView.View>
</ListView>
is the definition in my XAML file.
Then when a test starts, I run:
dataListView.ItemsSource = tr.TestResultCollection;
In TestRunner.cs, I have created the Observable Collection of ArrayLists as such:
ObservableCollection<ArrayList> _testResultCollection = new ObservableCollection<ArrayList>();
and publicly refer to them as such:
public ObservableCollection<ArrayList> TestResultCollection
{ get { return _testResultCollection; } }
Finally when I add to the collection, I use :
_testResultCollection.Add(SummaryVerificationTestCase1(dbs, dbd));
which adds an ArrayList to the collection. (Yes, a collection of ArrayLists, I know...)
However, what gets displayed in each Column is (Collection), (Collection, (Collection).
I see why. However, I'm not entirely certain what the neatest way around is. Normally in each GridViewColumn you give a binding like:
DisplayMemberBinding="{Binding TestResult}"
But the ArrayList doesn't have named components, just indices (0-2).
Is there a way to bind each column to the individual indices? Or have I missed something simple already?
Specify an index in the binding path:
<GridViewColumn Width="240" Header="Test" DisplayMemberBinding="{Binding Path=[0]}"/>
<GridViewColumn Width="50" Header="Result" DisplayMemberBinding="{Binding Path=[1]}"/>
<GridViewColumn Header="Column 3" DisplayMemberBinding="{Binding Path=[2]}"/>
I am developing a WPF application where i can read some properties from the windows services list which are currently running on my system.I am able to read the properties of a particular service and passing to a collection which in turn show up in my UI under a Listview.
I want the same scenario to be used for list of services .i.e.i am trying in the following way..but i am not sure where did i miss the point...
Here is my code
foreach (string serviceName in sList)
{
ServiceController controller = new ServiceController(serviceName);
StatusCollection.Add (new StatusData
{
Name = name,
Status = status
});
lvStatus.DataContext = StatusCollection;
lvStatus.ItemsSource = StatusCollection;
}
<ListView Height="166" HorizontalAlignment="Left" Margin="23,0,0,0" Name="lvStatus" VerticalAlignment="Top" Width="264" >
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"></GridViewColumn>
<GridViewColumn Header="Status" DisplayMemberBinding="{Binding Status}"></GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Remove the DataContext line of code.
If you set your ItemsSource in the code behind make sure you do it before InitializeComponent is called. If not, you will need to refresh your Items collection.
However, I would setup a View Model for your Window or Control which implements INotifyPropertyChanged. Create your collection as an ObservableCollection and bind to it in the XAML:
<ListView ... ItemsSource={Binding Path=ServiceList}>
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=Name}" />
<GridViewColumn Header="Status" DisplayMemberBinding="{Binding Path=Status}" />
</GridView>
</ListView.View>
</ListView>
Let me know if you need an example of using a View Model.
I have a listview in a WPF application which is supposed to display the contents of an observable collection. I had it displaying in an older build, but in trying to make the listview update more often I changed the XAML quite a lot and after putting it back it now doesn't display anything, ever.
Here is the XAML:
<TabItem GotFocus="TabSelect">
<TabItem.Header>
<TextBlock FontSize="12pt">error log</TextBlock>
</TabItem.Header>
<Grid><ListView Name="JfifoList" ItemsSource="{Binding JFifoErrorCollection}" Background="Transparent">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Time}" Header="time" Width="100" />
<GridViewColumn DisplayMemberBinding="{Binding FEStatus}" Header="fe status" Width="100" />
<GridViewColumn DisplayMemberBinding="{Binding BEStatus}" Header="be status" Width="100" />
<GridViewColumn DisplayMemberBinding="{Binding Trigger}" Header="trigger" Width="100" />
</GridView>
</ListView.View>
</ListView></Grid>
</TabItem>
I do set up the list's DataContext as "this" window:
JfifoList.DataContext = this;
When debugging I can see that the collection is populated, so there is data to display... Though also when debugging, I repeatedly see an error that says "A first chance exception of type 'System.NotSupportedException' occurred in PresentationFramework.dll" in the debug output.
EDIT: I've looked around some more and found that UI elements must be updated in the UI thread... for some reason (I haven't created any in the code) there are numerous threads running in my program, and they all seem to be updating my ObservableCollection... Don't know whether this might be the problem...
Modifications on the content of lists which are binded to a view, have to be done in a UI thread.
To catch your App UI thread, you can use something like this:
Application.Current.Dispatcher.Invoke(DispatcherPriority.Render, new Action(() => JfifoList = whateverData));
I have a user control that contains a listview. In the windows where I use this usercontrol, I want to be able to do something like what is shown below where I set the template for a control within the user control.
<ct:AutoCompleteComboBox
SelectedValue="{Binding Path=SelectedCountry}"
ItemsSource="{Binding Path=CountryList}" >
<ct:AutoCompleteComboBox.DropDownList >
<ListView
Background="Blue"
MinWidth="150"
MaxHeight="200">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header=" Name" DisplayMemberBinding="{Binding Name}" >
</GridViewColumn>
<GridViewColumn Header="Desc" DisplayMemberBinding="{Binding Description}" >
</GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
</ct:AutoCompleteComboBox.DropDownList>
</ct:AutoCompleteComboBox>
How do I go about doing this? I found that if I made AutoCompleteComboBox.DropDownList a dependency property, then the code would compile. However, this DropDownList property is not actually added to my control (it is added to the parent container of ct:AutoCompleteComboBox).
Any idea of the proper way to do this?
Thanks in advance
Bind subcontrol's property you want to be available outside to the property you created in the container control.
How to display treeview inside a list view, actually this listview has headers namely workbook, description,date, so when I display the tree view inside the listview, the treeview should open as per the listview headers.
My question is :
1. How to insert treeview inside Listview and my xaml code is
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ListView Name="lstViewWorkbooks" HorizontalAlignment="Left" >
<ListView.View >
<GridView >
<GridViewColumn Header="WorkBook" Width="200" DisplayMemberBinding="{Binding AnyWorkbook}" />
<GridViewColumn Header="Description" Width="660" DisplayMemberBinding="{Binding DescName}" />
<GridViewColumn Header="Date" Width="183" DisplayMemberBinding="{Binding WorkbookDate}" />
</GridView>
</ListView.View>
<TreeView HorizontalAlignment="Left" Margin="195,76,0,-76" Name="tviewPojectView" Width="120" />
</ListView>
</ScrollViewer>
I am using MVP architecture, with C# and wpf.
The treeview in the above xaml code is enough to display the data?
Please help me
Thanks
Ramm
If you want the tree view inside a cell in your grid, you need to place it inside the cell template for the correct column like this:
<GridViewColumn Header="WorkBook" Width="200" DisplayMemberBinding="{Binding AnyWorkbook}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TreeView HorizontalAlignment="Left" Margin="195,76,0,-76" Name="tviewPojectView" Width="120" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>