<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="buttonStack.MainWindow" x:Name="Window" Title="MainWindow" Width="640" Height="480" MinWidth="{Binding RelativeSource={RelativeSource Self}, Path=Content.MinWidth}"><DockPanel MinWidth="300"><Button x:Name="button1" Content="Button1" MinWidth="100"/><Button x:Name="button2" Content="Button2" MinWidth="100"/><Button x:Name="button3" Content="Button3" MinWidth="100"/></DockPanel> </Window>
WPF
Friday, September 13, 2013
Application minimum height determined by children minimum height
Monday, December 17, 2012
TreeListView in WPF
Window1.xaml
-----------------
<Window x:Class="SDKSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SampleApplication"
Title="HierarchicalDataTemplate Sample"
xmlns:src="clr-namespace:SDKSample">
<Window.Resources>
<ResourceDictionary>
<src:ListLeagueList x:Key="MyList"/>
<!--TreeListView-->
<!--Converter for Indentation of items-->
<local:TreeListViewConverter x:Key="TreeListViewConverter"/>
<!--Control Template for TreeViewItem's.-->
<ControlTemplate TargetType="TreeViewItem" x:Key="TreeListViewItem">
<!--Grid containing the current information and the subnodes.-->
<StackPanel>
<!--Border wrapping the content presenter.-->
<Border x:Name="Border" >
<!--GridViewRowPrsenter containing the current information.-->
<GridViewRowPresenter Content="{TemplateBinding Header}"
Columns="{Binding Columns,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=local:TreeListView}}"/>
</Border>
<!--ItemsPresenter containing the subnodes-->
<ItemsPresenter x:Name="ItemsPresenter" Visibility="Collapsed" />
</StackPanel>
<ControlTemplate.Triggers>
<!--Trigger used to show the sub items-->
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="ItemsPresenter" Property="Visibility" Value="Visible"/>
</Trigger>
<!--Trigger used to change the color based on selection-->
<Trigger Property="IsSelected" Value="true">
<!--Change the background color-->
<Setter TargetName="Border" Property="Background"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<!--Change the foreground color-->
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</Trigger>
<!--Trigger used to change the color based on selection-->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<!--Change the background color-->
<Setter TargetName="Border" Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<!--Change the foreground color-->
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</MultiTrigger>
<!--Trigger used to change the color based on the status of the item-->
<Trigger Property="IsEnabled" Value="false">
<!--Change the foreground color-->
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!--Control Template for TreeListViewExpander's.-->
<ControlTemplate TargetType="{x:Type local:TreeListViewExpander}" x:Key="TreeListViewExpander">
<StackPanel Orientation="Horizontal" x:Name="ContainerElement">
<!--Use a FrameworkElement to indent the button-->
<FrameworkElement Width="{Binding RelativeSource={x:Static RelativeSource.Self},
Converter={StaticResource TreeListViewConverter}}"/>
<!--Use a standard toggle button-->
<Expander IsExpanded="{Binding IsExpanded, RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=TreeViewItem}}" VerticalAlignment="Center" />
</StackPanel>
<ControlTemplate.Triggers>
<!--Trigger used to show/hide the expand button-->
<DataTrigger Binding="{Binding HasItems, RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=TreeViewItem}}" Value="False">
<Setter TargetName="ContainerElement" Property="Visibility" Value="Hidden"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!--Apply this style to all controls of type 'TreeListView'.-->
<Style TargetType="{x:Type local:TreeListView}">
<!--Set the control template.-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TreeListView}">
<ControlTemplate.Resources>
<!--Apply this style to all 'TreeViewItem's.-->
<Style TargetType="TreeViewItem">
<Setter Property="Template" Value="{StaticResource TreeListViewItem}"/>
<Setter Property="Margin" Value="0,8,0,0"/>
</Style>
<!--Apply this style to all 'TreeListViewExpander's.-->
<Style TargetType="local:TreeListViewExpander">
<Setter Property="Template" Value="{StaticResource TreeListViewExpander}"/>
</Style>
</ControlTemplate.Resources>
<!--Create a standard border around the 'TreeListView'.-->
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<!--ScrollViewer providing horizontal scrolling functionality
for both, content and headers.-->
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Disabled">
<!--Grid containing the header row and all the content rows.-->
<Grid>
<Grid.RowDefinitions>
<!--The header row.-->
<RowDefinition Height="Auto"/>
<!--The content row.-->
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--The header row.-->
<GridViewHeaderRowPresenter Columns="{TemplateBinding Columns}"
AllowsColumnReorder="{TemplateBinding AllowsColumnReorder}"/>
<!--ScrollViewer providing vertical scrolling
functionality for the content.-->
<ScrollViewer HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto"
Grid.Row="1">
<!--ItemsPresenter containg the content.-->
<ItemsPresenter/>
</ScrollViewer>
</Grid>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--TreeListView-->
<Style x:Key="newToggleButtonControlTemplate" TargetType="ToggleButton">
<Setter Property="Focusable" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Grid
Width="15"
Height="13"
Background="Transparent">
<Path x:Name="ExpandPath"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="1,1,1,1"
Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Expander} }"
Data="M 4 0 L 8 4 L 4 8 Z"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="True">
<Setter Property="Data"
TargetName="ExpandPath"
Value="M 0 4 L 8 4 L 4 8 Z"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type Expander}">
<Setter Property="Margin" Value="0,-1,0,0" />
<Setter Property="MinHeight" Value="20" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<Grid Background="{Binding Path=Background, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" x:Name="ContentRow"/>
</Grid.RowDefinitions>
<Border
x:Name="Border"
Grid.Row="0"
BorderThickness="{TemplateBinding BorderThickness}"
>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="16"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ToggleButton
Style="{StaticResource newToggleButtonControlTemplate}"
Background="{TemplateBinding Background}"
IsChecked="{Binding Path=IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
OverridesDefaultStyle="True"
/>
<ContentPresenter Grid.Column="1" RecognizesAccessKey="True" ContentSource="Header"/>
</Grid>
</Border>
<Border
x:Name="ExpandSite"
Grid.Row="1"
Visibility="Collapsed"
BorderThickness="{TemplateBinding BorderThickness}"
>
<ContentPresenter
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="{TemplateBinding Padding}"
Focusable="false"
/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter Property="Visibility" Value="Visible" TargetName="ExpandSite"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</Window.Resources>
<Grid x:Name="LayoutRoot" x:FieldModifier="public" Opacity="1" >
<local:TreeListView AllowsColumnReorder="True" x:Name="treeviewMain" x:FieldModifier="public" ItemsSource="{Binding Source={StaticResource MyList}}">
<!--Create an item template to specify the ItemsSource-->
<local:TreeListView.ItemTemplate>
<HierarchicalDataTemplate DataType = "{x:Type src:League}" ItemsSource = "{Binding Path=Divisions}"/>
</local:TreeListView.ItemTemplate>
<local:TreeListView.Columns>
<!--Create the first column containing the expand button and the type name.-->
<GridViewColumn Header="Name" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<!--The Expander Button (can be used in any column (typically the first one))-->
<local:TreeListViewExpander/>
<!--Display the name of the DataElement-->
<TextBlock Text="{Binding Path=Name}"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<!--Create a second column containing the number of children.-->
<GridViewColumn Header="Children" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox HorizontalAlignment="Center" IsChecked="{Binding IsChecked}"/>
<!--Display the size of the DataElement-->
<!--<TextBlock Text="{Binding Children.Count}" HorizontalAlignment="Right"/>-->
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<!--Create a third column containing the brush of the material.-->
<!--<GridViewColumn Header="Brush" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Border Background="{Binding Brush}" CornerRadius="2"
Width="16" Height="16"
BorderThickness="1" BorderBrush="DarkGray"/>
<TextBlock Text="{Binding Brush}"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>-->
</local:TreeListView.Columns>
<!--Create some sample data-->
<!--<MaterialGroup>
<MaterialGroup>
<DiffuseMaterial Brush="Blue"/>
<DiffuseMaterial Brush="Red"/>
<SpecularMaterial Brush="Orange"/>
</MaterialGroup>
<EmissiveMaterial Brush="AliceBlue"/>
</MaterialGroup>-->
</local:TreeListView>
</Grid>
</Window>
TreeListView.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;
namespace SampleApplication
{
/// <summary>
/// Represents a control that displays hierarchical data in a tree structure
/// that has items that can expand and collapse.
/// </summary>
public class TreeListView : TreeView
{
static TreeListView()
{
//Override the default style and the default control template
DefaultStyleKeyProperty.OverrideMetadata(typeof(TreeListView), new FrameworkPropertyMetadata(typeof(TreeListView)));
}
/// <summary>
/// Initialize a new instance of TreeListView.
/// </summary>
public TreeListView()
{
Columns = new GridViewColumnCollection();
}
#region Properties
/// <summary>
/// Gets or sets the collection of System.Windows.Controls.GridViewColumn
/// objects that is defined for this TreeListView.
/// </summary>
public GridViewColumnCollection Columns
{
get { return (GridViewColumnCollection)GetValue(ColumnsProperty); }
set { SetValue(ColumnsProperty, value); }
}
/// <summary>
/// Gets or sets whether columns in a TreeListView can be
/// reordered by a drag-and-drop operation. This is a dependency property.
/// </summary>
public bool AllowsColumnReorder
{
get { return (bool)GetValue(AllowsColumnReorderProperty); }
set { SetValue(AllowsColumnReorderProperty, value); }
}
#endregion
#region Static Dependency Properties
// Using a DependencyProperty as the backing store for AllowsColumnReorder. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AllowsColumnReorderProperty =
DependencyProperty.Register("AllowsColumnReorder", typeof(bool), typeof(TreeListView), new UIPropertyMetadata(null));
// Using a DependencyProperty as the backing store for Columns. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ColumnsProperty =
DependencyProperty.Register("Columns", typeof(GridViewColumnCollection),
typeof(TreeListView),
new UIPropertyMetadata(null));
#endregion
}
/// <summary>
/// Represents a control that can switch states in order to expand a node of a TreeListView.
/// </summary>
public class TreeListViewExpander : ToggleButton { }
//public class TreeListViewExpander1 : Expander { }
/// <summary>
/// Represents a convert that can calculate the indentation of any element in a class derived from TreeView.
/// </summary>
public class TreeListViewConverter : IValueConverter
{
public const double Indentation = 10;
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
//If the value is null, don't return anything
if (value == null) return null;
//Convert the item to a double
if (targetType == typeof(double) && typeof(DependencyObject).IsAssignableFrom(value.GetType()))
{
//Cast the item as a DependencyObject
DependencyObject Element = value as DependencyObject;
//Create a level counter with value set to -1
int Level = -1;
//Move up the visual tree and count the number of TreeViewItem's.
for (; Element != null; Element = VisualTreeHelper.GetParent(Element))
//Check whether the current elemeent is a TreeViewItem
if (typeof(TreeViewItem).IsAssignableFrom(Element.GetType()))
//Increase the level counter
Level++;
//Return the indentation as a double
return Indentation * Level;
}
//Type conversion is not supported
throw new NotSupportedException(
string.Format("Cannot convert from <{0}> to <{1}> using <TreeListViewConverter>.",
value.GetType(), targetType));
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException("This method is not supported.");
}
#endregion
}
}
Themes\Generic.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SampleApplication">
<!--Converter for Indentation of items-->
<local:TreeListViewConverter x:Key="TreeListViewConverter"/>
<!--Control Template for TreeViewItem's.-->
<ControlTemplate TargetType="TreeViewItem" x:Key="TreeListViewItem">
<!--Grid containing the current information and the subnodes.-->
<StackPanel>
<!--Border wrapping the content presenter.-->
<Border x:Name="Border">
<!--GridViewRowPrsenter containing the current information.-->
<GridViewRowPresenter Content="{TemplateBinding Header}"
Columns="{Binding Columns,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=local:TreeListView}}"/>
</Border>
<!--ItemsPresenter containing the subnodes-->
<ItemsPresenter x:Name="ItemsPresenter" Visibility="Collapsed"/>
</StackPanel>
<ControlTemplate.Triggers>
<!--Trigger used to show the sub items-->
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="ItemsPresenter" Property="Visibility" Value="Visible"/>
</Trigger>
<!--Trigger used to change the color based on selection-->
<Trigger Property="IsSelected" Value="true">
<!--Change the background color-->
<Setter TargetName="Border" Property="Background"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<!--Change the foreground color-->
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</Trigger>
<!--Trigger used to change the color based on selection-->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<!--Change the background color-->
<Setter TargetName="Border" Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<!--Change the foreground color-->
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</MultiTrigger>
<!--Trigger used to change the color based on the status of the item-->
<Trigger Property="IsEnabled" Value="false">
<!--Change the foreground color-->
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!--Control Template for TreeListViewExpander's.-->
<ControlTemplate TargetType="{x:Type local:TreeListViewExpander}" x:Key="TreeListViewExpander">
<StackPanel Orientation="Horizontal" x:Name="ContainerElement">
<!--Use a FrameworkElement to indent the button-->
<FrameworkElement Width="{Binding RelativeSource={x:Static RelativeSource.Self},
Converter={StaticResource TreeListViewConverter}}"/>
<!--Use a standard toggle button-->
<ToggleButton IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=TreeViewItem}}" Width="9" Height="9" VerticalAlignment="Center" Margin="1"/>
</StackPanel>
<ControlTemplate.Triggers>
<!--Trigger used to show/hide the expand button-->
<DataTrigger Binding="{Binding HasItems, RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=TreeViewItem}}" Value="False">
<Setter TargetName="ContainerElement" Property="Visibility" Value="Hidden"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!--Apply this style to all controls of type 'TreeListView'.-->
<Style TargetType="{x:Type local:TreeListView}">
<!--Set the control template.-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TreeListView}">
<ControlTemplate.Resources>
<!--Apply this style to all 'TreeViewItem's.-->
<Style TargetType="TreeViewItem">
<Setter Property="Template" Value="{StaticResource TreeListViewItem}"/>
</Style>
<!--Apply this style to all 'TreeListViewExpander's.-->
<Style TargetType="local:TreeListViewExpander">
<Setter Property="Template" Value="{StaticResource TreeListViewExpander}"/>
</Style>
</ControlTemplate.Resources>
<!--Create a standard border around the 'TreeListView'.-->
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<!--ScrollViewer providing horizontal scrolling functionality
for both, content and headers.-->
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Disabled">
<!--Grid containing the header row and all the content rows.-->
<Grid>
<Grid.RowDefinitions>
<!--The header row.-->
<RowDefinition Height="Auto"/>
<!--The content row.-->
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--The header row.-->
<GridViewHeaderRowPresenter Columns="{TemplateBinding Columns}"
AllowsColumnReorder="{TemplateBinding AllowsColumnReorder}"/>
<!--ScrollViewer providing vertical scrolling
functionality for the content.-->
<ScrollViewer HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto"
Grid.Row="1">
<!--ItemsPresenter containg the content.-->
<ItemsPresenter/>
</ScrollViewer>
</Grid>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Data.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.Collections.Generic;
namespace SDKSample
{
public class League
{
public League(string name)
{
_name = name;
bValue = true;
_divisions = new List<League>();
}
string _name;
bool bValue;
public string Name { get { return _name; } }
public bool IsChecked { get { return true; }
set
{
bValue = value;
}
}
List<League> _divisions;
public List<League> Divisions
{
get
{
return _divisions;
}
}
}
public class ListLeagueList : List<League>
{
public ListLeagueList()
{
League l;
League d;
League d1, d2;
Add(l = new League("League A"));
l.Divisions.Add((d = new League("Division A")));
d.Divisions.Add( d1 = new League("Team I"));
d1.Divisions.Add(d2 = new League("Team I.1.1"));
d2.Divisions.Add(new League("Team I.1.2"));
d2.Divisions.Add(new League("Team I.1.3"));
d1.Divisions.Add(new League("Team I.2"));
d1.Divisions.Add(new League("Team I.3"));
d.Divisions.Add(new League("Team II"));
d.Divisions.Add(new League("Team III"));
d.Divisions.Add(new League("Team IV"));
d.Divisions.Add(new League("Team V"));
l.Divisions.Add((d = new League("Division B")));
d.Divisions.Add(new League("Team Blue"));
d.Divisions.Add(new League("Team Red"));
d.Divisions.Add(new League("Team Yellow"));
d.Divisions.Add(new League("Team Green"));
d.Divisions.Add(new League("Team Orange"));
l.Divisions.Add((d = new League("Division C")));
d.Divisions.Add(new League("Team East"));
d.Divisions.Add(new League("Team West"));
d.Divisions.Add(new League("Team North"));
d.Divisions.Add(new League("Team South"));
Add(l = new League("League B"));
l.Divisions.Add((d = new League("Division A")));
d.Divisions.Add(new League("Team 1"));
d.Divisions.Add(new League("Team 2"));
d.Divisions.Add(new League("Team 3"));
d.Divisions.Add(new League("Team 4"));
d.Divisions.Add(new League("Team 5"));
l.Divisions.Add((d = new League("Division B")));
d.Divisions.Add(new League("Team Diamond"));
d.Divisions.Add(new League("Team Heart"));
d.Divisions.Add(new League("Team Club"));
d.Divisions.Add(new League("Team Spade"));
l.Divisions.Add((d = new League("Division C")));
d.Divisions.Add(new League("Team Alpha"));
d.Divisions.Add(new League("Team Beta"));
d.Divisions.Add(new League("Team Gamma"));
d.Divisions.Add(new League("Team Delta"));
d.Divisions.Add(new League("Team Epsilon"));
}
public League this[string name]
{
get
{
foreach (League l in this)
if (l.Name == name)
return l;
return null;
}
}
}
}
Subscribe to:
Posts (Atom)