Мне нужна горизонтально организованная ItemsControl
, которая ограничивает все свои элементы одинаковой шириной. Я использую элементы UserControl
s и строит TextBlock
с автоматическим размером, показывающий значение int (содержащееся в свойстве зависимостей) с Border
вокруг него. Проблема в том, что меньшие значения приводят к более узкому элементу, и мне нужно, чтобы все элементы были одинаковыми. Я рассмотрел несколько решений, но, похоже, я не могу заставить их работать.
Первый - установить для ItemsPanel
шаблона значение Grid
. Таким образом, я могу использовать выделенный код для генерации необходимого количества столбцов на основе источника данных и установить для всех значений ширины столбцов значение *
. Загадка заключалась в том, чтобы выяснить, как установить свойство столбца сетки для каждого элемента.
Второе решение - установить для ItemsPanel
шаблона значение StackPanel
. Это автоматически упорядочивает элементы правильно, но я не могу установить ширину каждого элемента равной ширине самого широкого элемента.
Последнее решение - установить для ItemsPanel
шаблона значение UniformGrid
с кодом для установки количества столбцов при каждом изменении источника данных. Это автоматически расположит элементы правильно и обеспечит равномерную ширину. Моя проблема здесь в том, что я не могу заставить что-либо показывать. Я попытался вручную добавить кнопки, и они показывают нормально. Мой UserControl
не появится. Я перечислил это решение ниже.
<Window x:Class="Learning_WPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:Learning_WPF"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="DateTape" Height="176" Width="500">
<Window.Resources>
<my:DateList x:Key="dateList" CollectionChanged="DateList_CollectionChanged" />
</Window.Resources>
<ItemsControl x:Name="itemsControl1" ItemsSource="{Binding Source={StaticResource dateList}, Path=/}" Grid.Row="1">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid x:Name="daysGrid" Rows="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Window>
public partial class MainWindow : Window
{
UniformGrid daysGrid;
DateList dateList;
public MainWindow()
{
InitializeComponent();
daysGrid = (UniformGrid)itemsControl1.ItemsPanel.LoadContent();
dateList = (DateList)FindResource("dateList");
dateList.Fill(DateTime.Today, DateTime.Today.AddDays(10));
}
private void DateList_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
daysGrid.Columns = dateList.Count;
}
}
public class DateList : ObservableCollection<Date>
{
public void Fill(DateTime first, DateTime last)
{
// implementation fills the array with all of the days between first and last, inclusively
}
}
Может быть, есть лучший способ сделать то, что я хочу достичь (возможно, немного графически, чем с помощью элементов управления) ...