Firstly let me clarify (if the title wasn't clear enough): I'm discussing System.Windows.Controls.DataGrid from the .NET 4.0 Framework, not the toolkit edition.
I have a data grid which i read in from a csv which can change with every load.
I am trying to create a simple search, I have been trying to use;
http://www.codeproject.com/KB/WPF/FirefoxLikeSearchWithMVVM.aspx
http://manfred-ramoser.blogspot.com/2009/11/search-highlighting-in-wpf-datagrid.html
and others, but there all seem very complicated for a simple task, can anyone help, just to be clear a filtering system is not want i am after, thank you.
For my project i did a search function this way :
i added a 'FilterResult' Boolean property to the ViewModel of my data. It is implementing NotifyPropertyChanged.
So i perform the filter on my list of object with simple foreach loop and i set/unset FilterResult
And in the 'Style' of the DataGridRow i put a Setter on Visibility depending upon this FilterResult
<Style TargetType="{x:Type DataGridRow}" x:Key="EventColorRowStyle">
<Style.Triggers>
<DataTrigger Binding="{Binding FilterResult}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
This simpler and much faster than using the Filter of a CollectionView, but still i can point you on what msdn says about it : http://msdn.microsoft.com/en-us/library/ff407126.aspx
Related
I've been trying to just hide items from a TreeView. I'm using a custom data type as source (called SettingsMenuItem) which inherits from FrameworkElement (currently FrameworkContentElement, because otherwise the TreeView renders them wrong).
My goal is by setting the VisibilityProperty of these FrameworkElements to either Collapsed or Visible that I'm able to hide certain items (including their children). I know that this can be done by deleting items from the source collection. But that's not what I want. It would mean that I have to mirror each collection in order to keep track of it's actual items, bind to each one in order to be notified about Visibility-changes and create a new collection each time one changes. A lot of overhead for this.
Right now I have no clue how I could accomplish that. I figure it's related to the ItemsGenerator, but I haven't seen any possibility to override it's behaviour. I thought TreeView would be able to detect Visibility, but obviously it doesn't. As alternative I thought of a custom TreeViewItem (maybe even TreeView if necessary) - but at this point the abstraction of this whole system overwhelms me. I don't know where to start and what is actually necessary to solve the problem.
Tips what I have to change or implement by myself would be more than enough. A complete solution would be nice.
You can do this using a data trigger bound to a property (e.g. "IsVisible") in you tree data nodes:
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsVisible}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
While this technically answers your question I would be wary of actually doing it. User3690202's comment is correct, it's the sort of thing you would normally do via filtering in your view model.
For alternate solution using code behind xaml.cs:
To Remove a specific TreeViewItem from a TreeView which is created from a code behind.
TreeViewItem treeViewItem1 = new TreeViewItem
{
Visibility = Visibility.Collapsed,
};
use the code with TreeViewItem you want to hide in a if condition to hide specific TreeViewItem Header let say "Cars" and you want to hide it and use the code with if condition to hide "Cars" TreeViewItem.
I am developing my first WPF Application, so I am not seasoned at all on WPF. I have the following situation:
I have a window that has a DataGrid control. The constructor of the window receives a DataTable as input. The Window class is as follows:
public partial class Project_Status_Window : Window {
//Required for the datacontext
public DataTable status { get; }
public Project_Status_Window(DataTable status) {
InitializeComponent();
this.DataContext = this;
this.status = status;
this.Show();
}
}
In order to display the table I am binding the status table in my XAML description of the window. As follows:
<DataGrid x:Name="Status_Table_Viewer" ItemsSource="{Binding status.DefaultView}"
AlternatingRowBackground="LightBlue" AlternationCount="1"
SelectionMode="Extended" SelectionUnit="Cell" ScrollViewer.CanContentScroll="True">
Now I want to change the background of the cells in one column (preferably selecting the column by name). However the background should be changed only if the value in the cells is contained in a list that is populated through a method that in turn invokes a database query. Since this is presentation logic I would like to keep it on the XAML side. I have been researching a lot and cannot find a similar case, though I believe that this can be done with DataTriggers, so I have the following code in XAML:
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="TextBlock.TextAlignment" Value="Center" />
<Style.Triggers>
<DataTrigger Value="True"> I have no Idea what to write in this tag
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
Let's assume that the window will have a method that receives a string as input and returns true or false depending on whether the string is missing in the database or not. The method will be the following:
public bool isMissingMat(string input)
I don't know how to access the data in a named column of my DataTable, pass the data to my custom method and then act on the formatting of the DataGrid based on the value of my method.
I understand what you want to achieve. Unfortunately, getting formatting working for a DataGrid is devilishly difficult and cannot be explained here to you step by step. Better just read my article CodeProject: Guide to WPF DataGrid formatting using bindings. It gives a lot of background information which you even cannot find on MSDN :-(
It has also a sample how you can change the background colour of a row based on business logic data, precisely what you need.
You wrote: "Since this is presentation logic I would like to keep it on the XAML side." That is not a good idea. XAML is good at defining static content, but horribly bad at doing simple logical stuff, like it can even not do addition or if-statements or debugging or ... Your life is MUCH easier, when you do dynamic stuff in code behind. Again, see my article to get a feeling what you should do in XAML and what is better done in code behind.
I'm writing an IM program on Windows Phone 8. And I am currently dealing with the UI for chatting.
I want to create a ListBox that holds all the "chat bubbles" (like those in iPhone). The incoming messages appear on the left-hand side, and outgoing messages on the right-hand side. Like this:
So obviously, I need to set differnt alignment for each item.
I was trying to solve this by wrapping the bubble in a large Grid that expands all the space in the ItemsPanel, and align the chat bubble to the right (the parent of the chat bubble is the large Grid). But that didn't work because a grid in ItemsPanel won't fill up all the spaces automatically. And then I went for searching "how to fill up all spaces in ItemsPanel" and no luck.
So, I think the only way to do this is to set different ItemsPanelTemplate for each ItemsPanel, to either "Right" or "Left".
Please, help me.. Thank you!
So how do you create a selector for different ItemsPanelTemplate?
You just need to customize the itemContainer :
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Style.Triggers>
<DataTrigger Binding="{Binding IsAnswer}" Value="True">
<Setter Property="HorizontalAlignment" Value="Right"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ItemsControl.ItemContainerStyle>
In case you dont have style triggers, you can use binding and a bool to HorizontalAlignment converter :
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="HorizontalAlignment" Value="{Binding IsAnswer,Converter={StaticResource AlignmentConverter}}"/>
</Style>
</ItemsControl.ItemContainerStyle>
you only need 2 View's for your messages aka DataTemplate
one for MyMsg and one for Answer both inhire from the Message class or interface (your decision) lets call it Msg
so you can set your ItemsSource to List<Msg> or ObservableCollection<Msg> and you are done
In an application I need to use some custom object where each have their own properties and these properties coming from a database so in
<Style x:Key="key1" TargetType="Rectangle">
<Setter Property="Stretch" Value="Fill"/>
<Setter Property="IsHitTestVisible" Value="False"/>
<Setter Property="s:Prop.ID" Value="1234567890-ABC" />
</Style>
I must assign values to the properties. Any help will be appreciated.
Thanks,
Amit
You can use TryFindResource(object key). For example, if your style is under your window's resources and you want to set the second setter to true, you can put this in the code-behind:
((TryFindResource("key1") as Style).Setters[1] as Setter).Value = true;
You could also use binding. Just set the value to Value="{Binding Path=path}" and make your path a dependency property. This also works with multibinding and conversion.
Perhaps MVVM will help you out. Then you have a ViewModel, which exposes your properties to the view. The Model is what the database will deliver. The ViewModel is an adapter between model and view.
Jason Dollinger explains it very good in his video which is available here
I have a requirement to show a list of items in a context menu. In addition to this, I need to show the frequently used items (configurable by user) on the top, followed by a separator, and then the standard list of all the items. I know, I can add all the items to context menu at runtime but I want to explore different options too. The question is - is it possible to:
Bind the standard list in xaml and then add the frequently used items at runtime.
OR
Bind the context menu to two separate list
OR
Any other better option
Please note that I need to maintain two separate lists due to some technical reasons.
I am not showing any existing code because this question may be considered as a generic question and may apply to any control.
The second option is doable using a CompositeCollection, however the binding capabilities are a bit dimished (cannot use DataContext, ElementName or RelativeSource) in the CollectionContainer.Collection-Binding.
This answer of mine on another question shows two ways in which you can bind. If you cannot make do with those restrictions you will have to create the composite collection in code-behind.
I would manage my menus in the ViewModels, not in the XAML. My ViewModel would be responsible for returning a collection that combines both the standard Menu collection, and the custom UserCollection.
Usually I separate the items with a null value, and use a DataTrigger to draw the template as a Separator if the item is null.
Something like this:
myMenu.AddRange(UserMenu);
myMenu.Add(null);
myMenu.AddRange(StandardMenu);
and the XAML...
<ContextMenu ItemsSource="{Binding MyMenu}">
<ContextMenu.Resources>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Template"
Value="{StaticResource MyMenuItemTemplate}" />
<Style.Triggers>
<DataTrigger Binding="{Binding }" Value="{x:Null}">
<Setter Property="Template"
Value="{StaticResource MySeparatorTemplate}" />
</DataTrigger>
</Style.Resources>
</Style>
</ContextMenu.Resources>
</ContextMenu>