效果如圖
單選
<Grid Margin="15,5,0,15">
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox Grid.Row="0" x:Name="singleHeader" Width="300" Height="30" PreviewMouseDown="singleHeader_PreviewMouseDown" HorizontalAlignment="Left" />
<Popup Grid.Row="1" x:Name="singlePopup" AllowsTransparency="True" IsOpen="False">
<TreeView x:Name="singleTree" ItemsSource="{Binding }" Initialized="singleTree_Initialized" SelectedItemChanged="singleTree_SelectedItemChanged">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" FontSize="18" Text="{Binding Name}" Margin="2,0,0,0"></TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Popup>
</Grid>
private void singleTree_Initialized(object sender, EventArgs e)
{
singleDataContext = new ObservableCollection<AdministrationViewModel>();
var beijing = new AdministrationViewModel() { Name = "北京市", Id = Guid.NewGuid().ToString() };
beijing.Children.Add(new AdministrationViewModel() { Name = "朝陽區", Id = Guid.NewGuid().ToString() });
beijing.Children.Add(new AdministrationViewModel() { Name = "海淀區", Id = Guid.NewGuid().ToString() });
beijing.Children.Add(new AdministrationViewModel() { Name = "通州區", Id = Guid.NewGuid().ToString() });
singleDataContext.Add(beijing);
var guangdong = new AdministrationViewModel() { Name = "廣東省", Id = Guid.NewGuid().ToString() };
guangdong.Children.Add(new AdministrationViewModel() { Name = "汕尾市", Id = Guid.NewGuid().ToString() });
guangdong.Children.Add(new AdministrationViewModel() { Name = "中山市", Id = Guid.NewGuid().ToString() });
var guangzhou = new AdministrationViewModel() { Name = "廣州市", Id = Guid.NewGuid().ToString() };
guangzhou.Children.Add(new AdministrationViewModel() { Name = "越秀區", Id = Guid.NewGuid().ToString() });
guangzhou.Children.Add(new AdministrationViewModel() { Name = "海珠區", Id = Guid.NewGuid().ToString() });
guangzhou.Children.Add(new AdministrationViewModel() { Name = "番禺區", Id = Guid.NewGuid().ToString() });
guangdong.Children.Add(guangzhou);
singleDataContext.Add(guangdong);
var trv = sender as TreeView;
trv.DataContext = singleDataContext;
}
private void singleTree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
var trv = sender as TreeView;
var trvItem = trv.SelectedItem as AdministrationViewModel;
//這里是否被選擇的條件為是否為葉子結點,也可以使用AdministrationViewModel中的屬性靈活控制
if (trvItem.Children.Count != 0) return;
singleHeader.Text = trvItem.Name.ToString();
singlePopup.IsOpen = false;
}
private void singleHeader_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
singlePopup.Placement = System.Windows.Controls.Primitives.PlacementMode.RelativePoint;
singlePopup.VerticalOffset = singleHeader.Height;
singlePopup.StaysOpen = true;
singlePopup.Height = singleTree.Height;
singlePopup.Width = singleHeader.Width;
singlePopup.IsOpen = true;
}
多選
<Grid Margin="15,5,0,15">
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox Grid.Row="0" x:Name="multiHeader" Width="300" Height="30" PreviewMouseDown="multiHeader_PreviewMouseDown" HorizontalAlignment="Left" />
<Popup Grid.Row="1" x:Name="multiPopup" AllowsTransparency="True" IsOpen="False">
<StackPanel Orientation="Vertical">
<TreeView x:Name="multiTree" ItemsSource="{Binding }" Initialized="multiTree_Initialized">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsChecked,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding IsCanChecked,Mode=OneWay}" Checked="CheckBox_CheckedOrUncheck" Unchecked="CheckBox_CheckedOrUncheck"></CheckBox>
<TextBlock VerticalAlignment="Center" FontSize="18" Text="{Binding Name}" Margin="2,0,0,0"></TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
<Button Content="Close(關閉)" Click="CloseMultiPopup_Click"></Button>
</StackPanel>
</Popup>
</Grid>
private void multiHeader_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
multiPopup.Placement = System.Windows.Controls.Primitives.PlacementMode.RelativePoint;
multiPopup.VerticalOffset = multiHeader.Height;
multiPopup.StaysOpen = true;
multiPopup.Height = multiTree.Height;
multiPopup.Width = multiHeader.Width;
multiPopup.IsOpen = true;
}
private void multiTree_Initialized(object sender, EventArgs e)
{
multiDataContext = new ObservableCollection<AdministrationViewModel>();
var beijing = new AdministrationViewModel() { Name = "北京市", Id = Guid.NewGuid().ToString() };
beijing.Children.Add(new AdministrationViewModel() { Name = "朝陽區", Id = Guid.NewGuid().ToString(),IsCanChecked=true });
beijing.Children.Add(new AdministrationViewModel() { Name = "海淀區", Id = Guid.NewGuid().ToString(), IsCanChecked = true });
beijing.Children.Add(new AdministrationViewModel() { Name = "通州區", Id = Guid.NewGuid().ToString() });
multiDataContext.Add(beijing);
var guangdong = new AdministrationViewModel() { Name = "廣東省", Id = Guid.NewGuid().ToString() };
guangdong.Children.Add(new AdministrationViewModel() { Name = "汕尾市", Id = Guid.NewGuid().ToString(), IsCanChecked = true });
guangdong.Children.Add(new AdministrationViewModel() { Name = "中山市", Id = Guid.NewGuid().ToString(), IsCanChecked = true });
var guangzhou = new AdministrationViewModel() { Name = "廣州市", Id = Guid.NewGuid().ToString() };
guangzhou.Children.Add(new AdministrationViewModel() { Name = "越秀區", Id = Guid.NewGuid().ToString(), IsCanChecked = true });
guangzhou.Children.Add(new AdministrationViewModel() { Name = "海珠區", Id = Guid.NewGuid().ToString(), IsCanChecked = true });
guangzhou.Children.Add(new AdministrationViewModel() { Name = "番禺區", Id = Guid.NewGuid().ToString(), IsCanChecked = true });
guangdong.Children.Add(guangzhou);
multiDataContext.Add(guangdong);
var trv = sender as TreeView;
trv.DataContext = multiDataContext;
}
private static void GetSelectList(List<AdministrationViewModel> selectList, AdministrationViewModel item)
{
if(item.Children!=null)
{
foreach (var child in item.Children)
{
if (child.IsCanChecked && child.IsChecked)
selectList.Add(child);
GetSelectList(selectList, child);
}
}
}
private void CheckBox_CheckedOrUncheck(object sender, RoutedEventArgs e)
{
var trv = multiTree;
var data = trv.DataContext as ObservableCollection<AdministrationViewModel>;
//獲得所有被勾選的選項:這里使用IsChecked和IsCanChecked進行判斷->可以根據業務改為其他的邏輯
var selectList = new List<AdministrationViewModel>();
foreach (var item in data)
{
if (item.IsCanChecked && item.IsChecked)
selectList.Add(item);
GetSelectList(selectList, item);
}
var selectStr = "";
foreach (var item in selectList)
{
selectStr += item.Name + ",";
}
selectStr = selectStr.TrimEnd(',');
multiHeader.Text = selectStr;
}
private void CloseMultiPopup_Click(object sender, RoutedEventArgs e)
{
multiPopup.IsOpen = false;
}