У меня проблема с настройкой видимости элемента управления при указании контекста с помощью ElementName. По какой-то причине wpf ведет себя по-разному при использовании ElementName, в отличие от использования контекста, установленного из выделенного кода.
Следующий код работает нормально. Коллекция содержит два элемента, и кнопка установлена в видимое состояние.
MainWindow.xaml
<Window x:Class="WpfObservableCollectionVisibility.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfObservableCollectionVisibility"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" x:Name="MyWindow">
<Window.Resources>
<ResourceDictionary>
<local:EmptyListVisibilityConverter x:Key="EmptyListVisibilityConverter"></local:EmptyListVisibilityConverter>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Button Height="50" Width="100" Content="Button" VerticalAlignment="top" Visibility="{Binding MenuItems, Converter={StaticResource EmptyListVisibilityConverter}}"></Button>
<Grid Width="200" Height="200">
<ItemsControl ItemsSource="{Binding MenuItems}" Focusable="False">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Grid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public static readonly DependencyProperty MenuItemsProperty =
DependencyProperty.Register(
"MenuItems", typeof(ObservableCollection<MyItem>),
typeof(MainWindow),
new FrameworkPropertyMetadata(default (ObservableCollection<MyItem>),FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)
);
public MainWindow()
{
InitializeComponent();
MenuItems = new ObservableCollection<MyItem>();
MenuItems.Add(new MyItem("Entry 1"));
MenuItems.Add(new MyItem("Entry 2"));
DataContext = this;
}
public ObservableCollection<MyItem> MenuItems
{
get => (ObservableCollection<MyItem>) GetValue(MenuItemsProperty);
set => SetValue(MenuItemsProperty, value);
}
}
public class MyItem
{
public MyItem(string name)
{
this.Name = name;
}
public string Name { get; set; }
}
public class EmptyListVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Trace.WriteLine($"Do conversion");
if (value == null)
{
Trace.WriteLine($"Conversion value was null");
return Visibility.Collapsed;
}
else
{
ICollection list = value as ICollection;
if (list != null)
{
if (list.Count == 0)
{
Trace.WriteLine($"Count is zero");
return Visibility.Hidden;
}
else
{
Trace.WriteLine($"Count is greater than zero");
return Visibility.Visible;
}
}
else
{
Trace.WriteLine($"Was not a collection");
return Visibility.Visible;
}
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Однако, когда я установить контекст ElementName для ItemsControl и Button, ItemsControl по-прежнему отображается нормально, но Button не отображается, потому что конвертер по какой-то причине получает пустую коллекцию.
<Button Height="50" Width="100" Content="Button" VerticalAlignment="top" Visibility="{Binding MenuItems, ElementName=MyWindow, Converter={StaticResource EmptyListVisibilityConverter}}"></Button>
...
<ItemsControl ItemsSource="{Binding MenuItems, ElementName=MyWindow}" Focusable="False">
Я попытался отладить его, но я не понимаю что не так. Я не знаю, откуда эта пустая коллекция. Я также не понимаю, почему ItemsControl работает нормально. Я чувствую, что либо оба должны работать, либо нет.