привязка шаблона ячейки в wpf

я просто программно создаю GridControl из devexpress и всех ячеек и привязываю его ItemsSource таким образом

var gridControlAzmayesh = new GridControl
            {
                View = tv,
                ItemsSource = new CollectionViewSource
                {
                    Source = list// include some column : id,name,last name 
                }.View
            };

теперь я хочу поместить кнопку в столбец и привязать ее по идентификатору, а при нажатии кнопки открыть пользовательский элемент управления с соответствующим идентификатором строки, но он не работает, мой код:

var template = new DataTemplate();
        var buttonFactory = new FrameworkElementFactory(typeof(Button)) ;
        buttonFactory.SetValue(Button.ContentProperty,"....");
        buttonFactory.SetBinding(Button.TagProperty, //????????add id to tag
            new Binding()
            {
                XPath = "Id", // ????????not binding work 
                UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
            });
        buttonFactory.AddHandler(ButtonBase.ClickEvent, new RoutedEventHandler((sender, args) =>
        {
            var aa = ((Button)sender).Tag; // ????????read tag
            var uc = new UcEditAzmayeshSabeghe((int) aa); // ???????? initialize a user control to open whit row id 
            UcPopupSabeghe.Child = uc;
            UcPopupSabeghe.Placement = PlacementMode.Mouse;
            UcPopupSabeghe.StaysOpen = false;
            UcPopupSabeghe.AllowsTransparency = true;
            UcPopupSabeghe.IsOpen = true;
        }));
        template.VisualTree = buttonFactory;
        gridControlAzmayesh.Columns.Add(new GridColumn
        {
            FieldName = "Id",
            Header = "...",
            CellTemplate = template,
            Width = new GridColumnWidth(40, GridColumnUnitType.Pixel)
        });
        gridControlAzmayesh.View = new TableView() { UseLightweightTemplates = UseLightweightTemplates.Row };

я не могу создать свой gridControl в XAML, потому что я создаю много gridControl с разными столбцами на разных вкладках: почему вы так боитесь XAML, я знаю, но XAML недостаточно гибок: ооочень много!

именно «id», не привязываясь к кнопке, я хочу получить идентификатор каждой строки и привязать его к свойствам тега кнопки.


person sadati    schedule 28.12.2019    source источник
comment
Какое управление сеткой вы используете? Каков ваш ожидаемый конечный результат (внешний вид). Почему бы вам не использовать GridView? Подробнее, пожалуйста. Ваша проблема должна быть воспроизводимой. По крайней мере понятно для тех, кто не знает деталей вашего проекта или задачи.   -  person BionicCode    schedule 28.12.2019
comment
@BionicCode я добавил некоторые детали.   -  person sadati    schedule 28.12.2019
comment
Как я уже говорил, привязка не работает, потому что вы неправильно ее настраиваете. Используйте Binding.Path вместо Binding.XPath. Смотрите мой ответ для рекомендуемого чистого и простого решения. Никогда не создавайте DataTemplate с помощью C#. Это самоубийственный стиль программирования.   -  person BionicCode    schedule 28.12.2019
comment
И, пожалуйста, поверьте мне, я не хочу вас обидеть, но когда вы говорите, что XAML недостаточно гибок, я предполагаю, что вам просто не хватает знаний. Это дает полную свободу для разработки пользовательского интерфейса. Не имеет значения, если каждый столбец выглядит по-разному. То, что вы делаете на С#, вполне достижимо только с помощью XAML. Мой ответ - делать то же, что и вы, но используя только XAML. Теперь скажите мне, какая версия лучше читается и выглядит проще. XAML предлагает множество способов достижения результатов. Например. XAML не нуждается в сложном FrameworkElementFactory. Все это скрыто от пользователя.   -  person BionicCode    schedule 28.12.2019
comment
Вы должны признать это. Просто посчитайте строки моего объявления разметки DataTemplate по сравнению с вашей версией C#.   -  person BionicCode    schedule 28.12.2019
comment
@BionicCode спасибо, но позвольте мне проверить ваш код, я вам верю. я скоро воспроизведу твой ответ   -  person sadati    schedule 28.12.2019
comment
Ладно, тестируй. Это может быть не совсем то, что вам нужно, поскольку я не знаю ваших точных требований. Ты никогда никому не говорил. Это пример намеренно упрощенный. Вы можете опираться на него наверняка.   -  person BionicCode    schedule 28.12.2019


Ответы (1)


Это быстрый, но четкий пример, показывающий, как создать представление сетки со столбцами, где один столбец содержит ToggleButton, который откроет Popup при нажатии:

DataItem.cs

// The data model for the ListView
public class DataItem
{
  public DataItem(int id)
  {
    this.Id = id;
  }
  public int Id { get; set; }
}

ViewModel.cs

// The data source for the view
class ViewModel
{
  // Binding source for the ListView.ItemsSource
  public ObservableCollection<DataItem> DataItems { get; set; }
  
  public ViewModel()
  {
    this.DataItems = new ObservableCollection<DataItem>() 
    {
      new DataItem(111), 
      new DataItem(112)
    };
  }
}

UcEditAzmayeshSabeghe.xaml.cs

// Example UserControl which will display in the opened Popup
public partial class UcEditAzmayeshSabeghe : UserControl
{
  public static readonly DependencyProperty IdProperty = DependencyProperty.Register(
    "Id",
    typeof(int),
    typeof(UcEditAzmayeshSabeghe),
    new PropertyMetadata(default(int)));

  public int Id { get => (int) GetValue(UcEditAzmayeshSabeghe.IdProperty); set => SetValue(UcEditAzmayeshSabeghe.IdProperty, value); }

  public UcEditAzmayeshSabeghe()
  {
    InitializeComponent();
  }
}

UcEditAzmayeshSabeghe.xaml

<UserControl x:Class="UcEditAzmayeshSabeghe"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d"
             d:DesignHeight="450"
             d:DesignWidth="800">
  <TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=UcEditAzmayeshSabeghe}, Path=Id}" />
</UserControl>

Применение

MainWindow.xaml

<Window>
  <Window.DataContext>
    <ViewModel />
  </Window.DataContext>

  <ListView ItemsSource="{Binding DataItems}">
    <ListView.View>
      <GridView>
        <GridViewColumn Header="ID"
                        DisplayMemberBinding="{Binding Id}"
                        Width="40" />
        <GridViewColumn Header="Details">
          <GridViewColumn.CellTemplate>
            <DataTemplate DataType="{x:Type DataItem}">
              <Grid>
                <ToggleButton x:Name="OpenPopupButton" Content="Show Details" />
                <Popup Placement="Mouse"
                       IsOpen="{Binding ElementName=OpenPopupButton, Path=IsChecked}"
                       StaysOpen="False"
                       AllowsTransparency="True">
                  <UcEditAzmayeshSabeghe Id="{Binding Id}" />
                </Popup>
              </Grid>
            </DataTemplate>
          </GridViewColumn.CellTemplate>
        </GridViewColumn>
      </GridView>
    </ListView.View>
  </ListView>
</Window>

Результат

введите здесь описание изображения

Это чистое решение, на которое приятно смотреть. Объявления XAML легко понять и легко поддерживать. Дизайн пользовательского интерфейса стал намного проще и многословнее.

person BionicCode    schedule 28.12.2019