wpfbindingcelltemplateframeworkelementfactory

binding celltemplate in wpf


i just create a GridControl from devexpress and all cell programmatically and bind its ItemsSource in this way

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

now i want to put a button in a column and bind it by id and when click in button open a user control whit corresponding row id but its not working my code is:

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 };

i cant create my gridControl in XAML because i create many gridControl with different Columns in many different Tab :Why are you so afraid of XAML i know, but XAML doesn't flexible enough :Sooo much!

exactly "id" not binding into a button i want to get every row id and bind it to a button tag properties.


Solution

  • This is a quick but clean example to show how to create a grid view with columns, where one column hosts a ToggleButton which will open a Popup once clicked:

    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>
    

    Usage

    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>
    

    Result

    enter image description here

    This solution is clean and a joy to look at. The XAML declarations are easy to understand and easy to maintain. UI design became much simpler and verbose.