Cannot display ListView data when creating PDF using PdfSharp.Xamarin.Forms - xamarin

I am new to xamarin and I am using PdfSharp.Xamarin.Forms nuget to create a PDF in Xamarin forms for both Android and iOS. Problem is I cannot render ListView. They have mentioned about it, and need to write a renderer for it. But I have no idea how to create and bind it.
This is how I did it.
<Grid x:Name="mainGrid">
<ScrollView>
<StackLayout Padding="4" Orientation="Vertical">
<!--<Image HeightRequest="80" Source="logojpeg.jpg" Margin="0,0,0,5"/>-->
<Label FontSize="18" TextColor="Black" FontFamily="{StaticResource timesNewRomanBold}" HorizontalOptions="CenterAndExpand" Text="Monthly Motor Renew List of Jayasekara (900585) as at January, 2020"/>
<Label FontSize="18" TextColor="Black" FontFamily="{StaticResource timesNewRomanBold}" HorizontalOptions="CenterAndExpand" Text="Report generated on 27 December, 2019" Margin="0,0,0,5"/>
<ListView x:Name="renewListView"
Footer=""
pdf:PdfRendererAttributes.ListRendererDelegate="{StaticResource PDFSampleListRendererDelegate}"
BackgroundColor="White"
SeparatorVisibility="None"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell IsEnabled="false">
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ScrollView>
</Grid>
In code behind.
public partial class MotorRenewalFinalPrint : ContentPage
{
public MotorRenewalFinalPrint()
{
InitializeComponent();
}
public MotorRenewalFinalPrint (List<MotorRenewalPrintData> newdd)
{
InitializeComponent ();
Title = "Save as PDF";
renewListView.ItemsSource = newdd;
}
private void pdf_Clicked(object sender, EventArgs e)
{
var pdf = PDFManager.GeneratePDFFromView(mainGrid);
var fileManager = DependencyService.Get<IFileIO>();
string filePath = Path.Combine(fileManager.GetMyDocumentsPath(), "formpdf.pdf");
DependencyService.Get<IPdfSave>().Save(pdf, filePath);
DependencyService.Get<IPDFPreviewProvider>().TriggerPreview(filePath);
}
}
Updated...
MainClass
public partial class MainPage : ContentPage
{
private List<Customer> Cus = new List<Customer>();
public MainPage()
{
InitializeComponent();
Customer ss1 = new Customer { Names = "test1", Ages = "10"};
Customer ss2 = new Customer { Names = "test2", Ages = "30" };
Cus.Add(ss1);
Cus.Add(ss2);
//rListView.ItemsSource = Cus;
}
private void Button_Clicked(object sender, System.EventArgs e)
{
var pdf = PDFManager.GeneratePDFFromView(mainGrid);
var fileManager = DependencyService.Get<IFileIO>();
string filePath = Path.Combine(fileManager.GetMyDocumentsPath(), "testpdf.pdf");
DependencyService.Get<IPdfSave>().Save(pdf, filePath);
DependencyService.Get<IPDFPreviewProvider>().TriggerPreview(filePath);
}
}
view
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TestPDF"
xmlns:pdf="clr-namespace:PdfSharp.Xamarin.Forms;assembly=PdfSharp.Xamarin.Forms"
x:Class="TestPDF.MainPage">
<ContentPage.Resources>
<ResourceDictionary>
<local:PDFSampleListRendererDelegate x:Key="PDFSampleListRendererDelegate" />
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<Grid x:Name="mainGrid">
<ScrollView>
<StackLayout Margin="0,0,0,5">
<Label Text="Welcome to Xamarin.Forms!" HorizontalOptions="CenterAndExpand" TextColor="Black" FontSize="18" VerticalOptions="Center" />
<ListView pdf:PdfRendererAttributes.ListRendererDelegate="{DynamicResource PDFSampleListRendererDelegate}" HeightRequest="150"/>
<Button Text="click" Clicked="Button_Clicked"/>
</StackLayout>
</ScrollView>
</Grid>
</ContentPage.Content>
</ContentPage>
PDFSampleListRendererDelegate
public class PDFSampleListRendererDelegate : PdfListViewRendererDelegate
{
public override void DrawCell(ListView listView, int section, int row, XGraphics page, XRect bounds, double scaleFactor)
{
XFont font = new XFont("times" ?? GlobalFontSettings.FontResolver.DefaultFontName, 15);
var yourObject = (listView.ItemsSource as List<Customer>).ElementAt(row);
page.DrawString(yourObject.Names, font, XBrushes.Black, bounds,
new XStringFormat
{
LineAlignment = XLineAlignment.Center,
Alignment = XStringAlignment.Center,
});
}
public override void DrawFooter(ListView listView, int section, XGraphics page, XRect bounds, double scaleFactor)
{
base.DrawFooter(listView, section, page, bounds, scaleFactor);
}
public override double GetFooterHeight(ListView listView, int section)
{
return base.GetFooterHeight(listView, section);
}
}

you should override DrawCell method
i.e:
public override void DrawCell(ListView listView, int section, int row, XGraphics page, XRect bounds, double scaleFactor)
{
XFont font = new XFont(yourCustomFont ?? GlobalFontSettings.FontResolver.DefaultFontName, label.FontSize * scaleFactor);
var yourObject = (listView.ItemSource as List<YourObjType>).ElementAt(row);
page.DrawString(yourObject.Text, font, XColors.Black, bounds,
new XStringFormat {
LineAlignment = XLineAlignment.Center,
Alignment = XStringAlignment.Center,
});
}

Related

how to refer to item in an enumeration within a ListView

I have a class MRU which contains an ObservableCollection of type string. I would like to display the items within the collection on a PopupPage in a ListView.
[DefaultBindingProperty("Items")]
public class MRU<T> :INotifyPropertyChanged
{
public ObservableCollection<T> Items { get; } = new ObservableCollection<T>();
// This is the maximum number of items that will be saved to persistent storage,
// in use the list can grow beyond this number
private int _MaxItems = 5;
public int MaxItems
{
get { return _MaxItems; }
set {
_MaxItems = value;
TrimItems();
OnPropertyChanged();
}
}
public void Add(T t) {
int idx = Items.IndexOf(t);
if (idx > 0)
{
Items.Move(idx, 0);
}
else if (idx == -1)
{
Items.Insert(0, t);
}
}
public T Pop(int i)
{
if (i > 0 && i < Items.Count)
{
Items.Move(i, 0);
}
return Items[0];
}
private void TrimItems()
{
while (Items.Count > _MaxItems)
{
Items.RemoveAt(Items.Count - 1);
}
}
public void Save()
{
App.Current.Properties["MRU"] = SaveToJSON();
App.Current.SavePropertiesAsync();
}
public string SaveToJSON()
{
TrimItems();
string jsonString = JsonSerializer.Serialize(Items);
return jsonString;
}
public int LoadFromJSON(string jsonString)
{
Items.Clear();
ObservableCollection<T> restore = JsonSerializer.Deserialize<ObservableCollection<T>>(jsonString);
foreach (var t in restore)
{
if (Items.Count == _MaxItems) break;
Items.Add(t);
}
return Items.Count;
}
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public event PropertyChangedEventHandler PropertyChanged;
}
I can display it in my page using the following XAML
<StackLayout
VerticalOptions="Center"
HorizontalOptions="Center"
Padding="0,20">
<Frame BackgroundColor="White" CornerRadius="15">
<StackLayout>
<Label Text="Most Recently Used" FontSize="Large" BackgroundColor="LightBlue" HorizontalOptions="CenterAndExpand" Padding="20,4"/>
<StackLayout >
<ListView ItemsSource="{Binding Items}" SelectionMode="Single">
<!--<ListView.ItemTemplate>
<DataTemplate>
<StackLayout Orientation="Vertical">
<Label Text="{Binding XXXXXX}" VerticalOptions="Center" HorizontalTextAlignment="End" FontSize="Medium"/>
</StackLayout>
</DataTemplate>
</ListView.ItemTemplate> -->
</ListView>
</StackLayout>
</StackLayout>
</Frame>
</StackLayout>
Note the commented out ListView.ItemTemplate section. I would like to display the items within an ItemTemplate so that I can add buttons for each object, however I don't know how to declare it . What should XXXXX be? I've tried a zillion unlikely things
In your xaml page, you created a ListView. I found that you forgot to add <ViewCell></ViewCell> tags.
You should use a structure like the following:
<ListView x:Name="listView">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
If you have an ObservableCollection<string>, to access the string in your binding, you want to do:
Text="{Binding}"
or
Text="{Binding .}"
Both say that you want to bind to whole object. Since the "whole object" in this case is a string, that's what you'll get.

Adding content on a custom content page

Ok, so I am trying to add a searchbar in the toolbar of my page.
The Search bar appears correctly in the toolbar and I can catch the on text changed event.
I created a new Xaml and cs page and changed content page to 'MySearchContentPage'
I Tried to add a grid and label on my new page created but nothing will show except for the searchbar. I added this just to see if I can get anything to display.
Am I adding it in the right place ? Or how do you add content to this page ?
I have done this by doing the following:
MySearchContentPage Class:
public class MySearchContentPage : ContentPage, ISearchPage
{
public MySearchContentPage()
{
SearchBarTextChanged += HandleSearchBarTextChanged;
}
public event EventHandler<string> SearchBarTextChanged;
public void OnSearchBarTextChanged(string text) => SearchBarTextChanged?.Invoke(this, text);
void HandleSearchBarTextChanged(object sender, string searchBarText)
{
//Logic to handle updated search bar text
}
}
ISearchPage:
public interface ISearchPage
{
void OnSearchBarTextChanged(string text);
event EventHandler<string> SearchBarTextChanged;
}
iOS renderer page:
public class MySearchContentPageRenderer : PageRenderer, IUISearchResultsUpdating
{
readonly UISearchController searchController;
bool _isFirstAppearing = true;
public override void WillMoveToParentViewController(UIViewController parent)
{
base.WillMoveToParentViewController(parent);
var searchController = new UISearchController(searchResultsController: null)
{
SearchResultsUpdater = this,
DimsBackgroundDuringPresentation = false,
HidesNavigationBarDuringPresentation = true,
HidesBottomBarWhenPushed = true
};
searchController.SearchBar.Placeholder = "Search Symptoms";
parent.NavigationItem.SearchController = searchController;
DefinesPresentationContext = true;
}
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
//Work-around to ensure the SearchController appears when the page first appears https://stackoverflow.com/a/46313164/5953643
if (_isFirstAppearing)
{
ParentViewController.NavigationItem.SearchController.Active = true;
ParentViewController.NavigationItem.SearchController.Active = false;
_isFirstAppearing = false;
}
}
public void UpdateSearchResultsForSearchController(UISearchController searchController)
{
if (Element is ISearchPage searchPage)
searchPage.OnSearchBarTextChanged(searchController.SearchBar.Text);
}
public MySearchContentPageRenderer()
{
var searchControllerr = new UISearchController(searchResultsController: null)
{
SearchResultsUpdater = this,
DimsBackgroundDuringPresentation = false,
HidesNavigationBarDuringPresentation = false,
HidesBottomBarWhenPushed = true
};
searchControllerr.SearchBar.Placeholder = string.Empty;
}
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
UINavigationBar.Appearance.TitleTextAttributes = new UIStringAttributes
{
ForegroundColor = UIColor.Red
};
}
public override void ViewDidLoad()
{
// base.ViewDidLoad();
// NavigationController.NavigationBar.PrefersLargeTitles = true;
// NavigationController.NavigationBar.BackgroundColor = UIColor.Red;
// var searchController = new UISearchController(searchResultsController: null);
// searchController.SearchBar.SearchBarStyle = UISearchBarStyle.Default;
// searchController.SearchBar.BackgroundColor = UIColor.Green;
// NavigationItem.SearchController = searchController;
// NavigationItem.HidesSearchBarWhenScrolling = false;
//searchController.SearchBar.SizeToFit();
//searchController.SearchBar.SearchBarStyle = UISearchBarStyle.Prominent;
////NavigationController.TabBarController
//this.sea
//NavigationController.TabBarController.NavigationItem.HidesSearchBarWhenScrolling = true;
//NavigationController.TabBarController.NavigationItem.SearchController = searchController;
//this.Title = "Search";
}
}
So far the outcome is this :
I can't seem to get anything else to add to this page. Can anyone explain why?
AddSymptomNew.xaml page:
<?xml version="1.0" encoding="UTF-8"?>
<visiblegyapp:MySearchContentPage
xmlns:visiblegyapp="clr-namespace:VisiblegyApp"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="VisiblegyApp.AddSymptomNew"
xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
ios:Page.LargeTitleDisplay="Always"
Title="Search Symptoms"
BackgroundColor="{DynamicResource BasePageColor}"
>
<ScrollView
x:Name="outerScrollView"
Padding="0"
>
<Grid
x:Name="layeringGrid"
RowSpacing="0"
VerticalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Text="test label" TextColor="Red" Grid.Row="1"/>
</Grid>
</ScrollView>
The cause is ContentPage is inheritable while XAML is not inheritable.
I would recommend you to use a custom contentview and add this contentView to MySearchContentPage .
For example, create a custom contentView here:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}
And in Xaml:
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="App132.AddSymptomNewView">
<ContentView.Content>
<ScrollView
x:Name="outerScrollView"
Padding="0">
<Grid
x:Name="layeringGrid"
RowSpacing="0"
VerticalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Text="test label" TextColor="Red" Grid.Row="1"/>
</Grid>
</ScrollView>
</ContentView.Content>
</ContentView>
And use it in the MySearchContentPage :
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:app132="clr-namespace:App132"
mc:Ignorable="d"
x:Class="App132.MainPage">
<app132:AddSymptomNewView/>
</ContentPage>

How to show Navigationbar 'TitleView' Common for all pages

I have added TitleView in MainPage to show on Navigationbar but it shows only for MainPage when I navigate to some other page Navigationbar displaying empty.
Below code I have in MainPage.xaml file
<NavigationPage.TitleView>
<RelativeLayout HorizontalOptions="Fill"
<Image Source="bell.png" HeightRequest="25" WidthRequest="25" x:Name="imgBell"
RelativeLayout.YConstraint="{ConstraintExpression
Type=RelativeToParent,
Property=Height,
Factor=0.018,Constant=10}">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding GetStaffAnnouncementCommand}"></TapGestureRecognizer>
</Image.GestureRecognizers>
</Image>
<Label FontSize="10" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" BackgroundColor="Transparent" Text="2" TextColor="Red"
HeightRequest="22" WidthRequest="23" x:Name="labelText">
</Frame>
</RelativeLayout>
</NavigationPage.TitleView>
When I click on bell icon and move to second page TitleView not displaying at all
How can I display TitleView common for all pages?
I wrote a demo about your needs.
There is GIF.
You could Write a custom page inherits from 'ContentPage' and add toolbar item to it.
Update
I achieve it with DependencyService, If you want to know more details about how to achieve DependencyService, you could refer to this blog and my code.
https://www.xamboy.com/2018/03/08/adding-badge-to-toolbaritem-in-xamarin-forms/
There is code that used DependencyService.
Custom ToolbarPage
public class ToolbarPage : ContentPage
{
public ToolbarItem toolbarItem;
public static int item;
public ToolbarPage()
{
// public ToolbarItem(string name, string icon, Action activated, ToolbarItemOrder order = ToolbarItemOrder.Default, int priority = 0);
toolbarItem =new ToolbarItem();
toolbarItem.Icon = "ring2.png";
toolbarItem.Order = ToolbarItemOrder.Primary;
// toolbarItem.Text = item+"";
toolbarItem.Priority = 0;
toolbarItem.Clicked += ToolbarItem_Clicked;
ToolbarItems.Add(toolbarItem);
if (item >= 1)
{
DependencyService.Get<IToolbarItemBadgeService>().SetBadge(this, toolbarItem, $"{item}", Color.Red, Color.White);
}
}
private void ToolbarItem_Clicked(object sender, EventArgs e)
{
item = item + 1;
DependencyService.Get<IToolbarItemBadgeService>().SetBadge(this, toolbarItem, $"{item}", Color.Red, Color.White);
}
}
Main.cs
public partial class MainPage : ToolbarPage
{
public MainPage()
{
InitializeComponent();
bt1.Text = ToolbarPage.item.ToString();
bt1.Clicked += async (o, e) =>
{
await Navigation.PushAsync(new HelloToolbarInher());
};
}
protected override async void OnAppearing()
{
//You must make a delay,
await Task.Delay(100);
bt1.Text = ToolbarPage.item.ToString();
DependencyService.Get<IToolbarItemBadgeService>().SetBadge(this, toolbarItem, $"{ToolbarPage.item}", Color.Red, Color.White);
}
}
Do not forget to change MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<local:ToolbarPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:NaviagationViewDemo"
x:Class="NaviagationViewDemo.MainPage">
<StackLayout>
<!-- Place new controls here -->
<Button
x:Name="bt1"
Text="click"
></Button>
</StackLayout>
There is my new demo.
https://github.com/851265601/NewNaviagationViewDemo

Multi-select Listview

This is my list view it should contain the list of activities came from my SQLite database:
<ListView SeparatorVisibility="None" x:Name="lstActivity" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame StyleClass="lstframe" CornerRadius="0" BorderColor="Transparent" HasShadow="False">
<StackLayout StyleClass="lstContainer" VerticalOptions="CenterAndExpand">
<Grid>
<Label StyleClass="lstActivityName" Grid.Row="0" Grid.Column="0" Text="{Binding ActivityDescription}">
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="Android" Value="Poppins-Regular.otf#Poppins-Regular"/>
</OnPlatform>
</Label.FontFamily>
</Label>
<Switch Grid.Row="0" Grid.Column="1" IsToggled="{Binding Selected}" />
</Grid>
</StackLayout>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Here is how I populate the list view this will return atleast five(5) activities:
public void Get_Activities()
{
try
{
var db = DependencyService.Get<ISQLiteDB>();
var conn = db.GetConnection();
var getActivity = conn.QueryAsync<ActivityTable>("SELECT * FROM tblActivity WHERE Deleted != '1' ORDER BY ActivityDescription");
var resultCount = getActivity.Result.Count;
if (resultCount > 0)
{
var result = getActivity.Result;
lstActivity.ItemsSource = result;
lstActivity.IsVisible = true;
}
else
{
lstActivity.IsVisible = false;
}
}
catch (Exception ex)
{
//Crashes.TrackError(ex);
}
}
Selected item binding:
public class SelectData
{
public bool Selected { get; set; }
}
Get selected Items on click:
private void BtnClose_Clicked(object sender, EventArgs e)
{
foreach (var x in result)
{
if (x.Selected)
{
// do something with the selected items
}
}
}
I posted another question regarding on multi-select list view my problem is I don't know how to proceed when I use the answers given to me. How can I get the the selected values because I will save the selected values to my database?
your Switch is bound to the Selected property of your model. Just iterate (or use LINQ) to get the items that are selected.
// you need to maintain a reference to result
foreach(var x in result)
{
if (x.Selected)
{
// do something with the selected items
}
}
LINQ
var selected = result.Where(x => x.Selected).ToList();
you will also need to have a class level reference to result
// you will need to change this to reflect the actual type of result
List<MyClass> result;
public void Get_Activities()
{
...
result = getActivity.Result;
...
For multi-select Listview, I have wrote a working example in my blog. Hope this helps : https://androidwithashray.blogspot.com/2018/03/multiselect-list-view-using-xamarin.html?view=flipcard

How to change Foreground color of TextBlock in DataTemplate from code on Windows Phone?

I'd like to change Foreground color of TextBlock (bellow TitleText and DateText) in DataTemplate from code.
<ListBox x:Name="listBox1" ItemsSource="{Binding}" ScrollViewer.ManipulationMode="Control" SelectionChanged="listBox1_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="stackPanel1" HorizontalAlignment="Stretch" Orientation="Horizontal">
<TextBlock FontSize="35" x:Name="TitleText" Text="{Binding Title}" Width="386" Foreground="Black" />
<TextBlock FontSize="25" x:Name="DateText" Text="{Binding Date}" Width="78" Foreground="Black" />
<TextBlock x:Name="Id" Text="{Binding Id}" Visibility="Collapsed" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I'd like to do like this in code behind. But It seems not be able to access x:Name property in DataTemplate.
this.TitleText.Foreground = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0);
Does anyone know a good solution for this ?
Why don't you do it the Fast way instead of crawling the Visual Tree.
<TextBlock FontSize="35" Text="{Binding Title}" Width="386" Foreground="[Binding Color}" />
Then all you have to do is:
Add a Color Brush Property in your Collection
Change this property to the color you want
Make sure this property implement INotify or is a Dependency Property
Example
XAML
<Grid>
<ListBox ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment="Stretch" Orientation="Horizontal">
<TextBlock Text="{Binding Title}" Foreground="{Binding TitleColor}" />
<TextBlock Text="{Binding Date}" Foreground="Black" />
<TextBlock Text="{Binding Id}" Visibility="Collapsed" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
CodeBehind
public partial class MainPage : Page
{
public ObservableCollection<TEST> TestCollection { get; private set; }
public MainWindow()
{
InitializeComponent();
TestCollection = new ObservableCollection<TEST>();
TestCollection.Add(new TEST()
{
TitleColor = Brushes.Black,
ID = 0,
Title = "A",
Date = DateTime.Now,
});
TestCollection.Add(new TEST()
{
TitleColor = Brushes.Red,
ID = 1,
Title = "B",
Date = DateTime.Now.AddDays(1),
});
DataContext = TestCollection;
}
}
public class TEST : INotifyPropertyChanged
{
private Brush _TitleColor;
public Brush TitleColor
{
get
{
return _TitleColor;
}
set
{
_TitleColor = value;
OnPropertyChanged("TitleColor");
}
}
private int _ID;
public int ID
{
get
{
return _ID;
}
set
{
_ID = value;
OnPropertyChanged("ID");
}
}
private string _Title;
public string Title
{
get
{
return _Title;
}
set
{
_Title = value;
OnPropertyChanged("Title");
}
}
private DateTime _Date;
public DateTime Date
{
get
{
return _Date;
}
set
{
_Date = value;
OnPropertyChanged("Date");
}
}
public TEST()
{
}
#region INotifyProperty
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
#endregion
}
You can use FindItem method to find element in visual tree by it name and then change it Foregorund.
((listBox.ItemContainerGenerator.ContainerFromIndex(5) as FrameworkElement).FindName("TitleText") as TextBlock).Foreground = new SolidColorBrush(Color.FromArgb(255, 128, 128, 128));
where 5 is your item index
To Expand on MyKuLLSKI's answer, if your change is based on some value already in your object (eg. an int property that is greater than 5), you could use a ValueConverter (see here for an example) to read the value and return a brush. That is cleaner than adding a colour to your model since it is (arguably) UI related rather than data related.
MyKuLLSKI gave me perfect solution. But I couldn't make it.
I was struggling and I found my problem. I wrote the answer (only for me ) in my blog. Please take a glance it.
Cannot bind two types of data source to one UI target
http://myprogrammingdial.blogspot.com/2012/03/cannot-bind-two-types-of-data-source-to.html

Resources