wpf Itemscontrol内的用户控件绑定[重复]

j5fpnvbx  于 2023-02-16  发布在  其他
关注(0)|答案(1)|浏览(253)
    • 此问题在此处已有答案**:

DependencyProperty not triggered(2个答案)
昨天关门了。
这篇文章是昨天编辑并提交审查的。
编辑:
正在调用PropertyChangedCallback函数,但问题是只有绑定在我的itemscontrol中时它才不起作用。如果不在itemscontrol中,它才起作用!uc:datagrid is not inside an itemscontrol it is working!

public ObservableCollection<int> SelectedCells
    {
        get { return (ObservableCollection<int>)GetValue(SelectedCellsProperty); }
        set { SetValue(SelectedCellsProperty, value); }
    }

    public static readonly DependencyProperty SelectedCellsProperty =
        DependencyProperty.Register("SelectedCells", typeof(ObservableCollection<int>), typeof(DataGrid), new PropertyMetadata(null, new PropertyChangedCallback(OnSelectedCellsChanged)));

    private static void OnSelectedCellsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // This method will be called whenever the value of the SelectedCells property changes
        // You can perform any additional logic you need to here
        Console.WriteLine("change"); <-- This is getting called, also if in my itemscontrol
    }

ItemsControl内部的绑定有问题。
我想知道当前在Datagrid(用户控件内)中选择了哪些单元格。
这是我的Datagrid用户控件。我在这里添加了一个依赖属性SelectedCells。

/// <summary>
/// Interaction logic for DataGrid.xaml
/// </summary>
public partial class DataGrid : UserControl
{
    public DataGrid()
    {
        InitializeComponent();
        SelectedCells = new ObservableCollection<int>();
    }

    public DataGridValue DataGridSource
    {
        get { return (DataGridValue)GetValue(DataGridSourceProperty); }
        set { SetValue(DataGridSourceProperty, value); }
    }

    public static readonly DependencyProperty DataGridSourceProperty =
        DependencyProperty.Register("DataGridSource", typeof(DataGridValue), typeof(DataGrid), new PropertyMetadata(null));

    public ObservableCollection<int> SelectedCells
    {
        get { return (ObservableCollection<int>)GetValue(SelectedCellsProperty); }
        set { SetValue(SelectedCellsProperty, value); }
    }

    public static readonly DependencyProperty SelectedCellsProperty =
        DependencyProperty.Register("SelectedCells", typeof(ObservableCollection<int>), typeof(DataGrid), new PropertyMetadata(null));

    private void datagrid_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
    {
        SelectedCells = new ObservableCollection<int>();

        foreach (DataGridCellInfo cellInfo in datagrid.SelectedCells)
        {
            int columnIndex = cellInfo.Column.DisplayIndex;
            int rowIndex = datagrid.ItemContainerGenerator.IndexFromContainer(
                datagrid.ItemContainerGenerator.ContainerFromItem(cellInfo.Item));
            //Console.WriteLine($"Cell ({rowIndex}, {columnIndex}) is selected.");

            switch((DayName)columnIndex)
            {
                case 0: break;
                case DayName.Mo: 
                    if (DataGridSource.DataGridList[rowIndex].MondayCell.Text != string.Empty)
                    {
                        SelectedCells.Add(Convert.ToInt32(DataGridSource.DataGridList[rowIndex].MondayCell.Text));
                    }
                    break;
                case DayName.Di:
                    if (DataGridSource.DataGridList[rowIndex].TuesdayCell.Text != string.Empty)
                    {
                        SelectedCells.Add(Convert.ToInt32(DataGridSource.DataGridList[rowIndex].TuesdayCell.Text));
                    }
                    break;
                case DayName.Mi:
                    if (DataGridSource.DataGridList[rowIndex].WednesdayCell.Text != string.Empty)
                    {
                        SelectedCells.Add(Convert.ToInt32(DataGridSource.DataGridList[rowIndex].WednesdayCell.Text));
                    }
                    break;
                case DayName.Do:
                    if (DataGridSource.DataGridList[rowIndex].ThursdayCell.Text != string.Empty)
                    {
                        SelectedCells.Add(Convert.ToInt32(DataGridSource.DataGridList[rowIndex].ThursdayCell.Text));
                    }
                    break;
                case DayName.Fr:
                    if (DataGridSource.DataGridList[rowIndex].FridayCell.Text != string.Empty)
                    {
                        SelectedCells.Add(Convert.ToInt32(DataGridSource.DataGridList[rowIndex].FridayCell.Text));
                    }
                    break;
                case DayName.Sa:
                    if (DataGridSource.DataGridList[rowIndex].SaturdayCell.Text != string.Empty)
                    {
                        SelectedCells.Add(Convert.ToInt32(DataGridSource.DataGridList[rowIndex].SaturdayCell.Text));
                    }
                    break;
                case DayName.So:
                    if (DataGridSource.DataGridList[rowIndex].SundayCell.Text != string.Empty)
                    {
                        SelectedCells.Add(Convert.ToInt32(DataGridSource.DataGridList[rowIndex].SundayCell.Text));
                    }
                    break;
            }
        }
    }
}

        <DataGrid x:Name="datagrid"
          CanUserAddRows="False"
          CanUserDeleteRows="False"
          CanUserResizeColumns="False"
          CanUserReorderColumns="False"
          CanUserResizeRows="False"
          CanUserSortColumns="False"
          AutoGenerateColumns="False" 
          SelectionUnit="Cell"
          SelectionMode="Extended"
          HeadersVisibility="Column"
          Background="Transparent"
          BorderBrush="Transparent"
          SelectedCellsChanged="datagrid_SelectedCellsChanged"
          ItemsSource="{Binding DataGridSource.DataGridList, RelativeSource={RelativeSource AncestorType=UserControl}}"
          >

如果我只是将DataGrid添加到我的mainView,绑定就可以正常工作:

<uc:DataGrid Height="160" Width="300" 
                             HorizontalAlignment="Center"
                             VerticalAlignment="Center"
                             DataGridSource="{Binding TestGrid}"
                             SelectedCells="{Binding TestList, Mode=TwoWay}"
                             Margin="20,20,0,0"/>

属性:

public partial class MainViewModel : BaseViewModel
{
    private ObservableCollection<int> testList;
    public ObservableCollection<int> TestList
    {
        get
        {
            if (testList == null)
            {
                testList = new ObservableCollection<int>();
            }
            return testList;
        }
        set
        {
            testList = value;
        }
    }

但如果我在Itemscontrol内部执行此操作,则绑定不起作用。我希望它绑定到我的MainViewModel内部的Property。在调试器中没有绑定问题,但从未调用setter。
这是我的ItemsControl:

<ItemsControl Name="MyItemsControl" Visibility="Visible"
                  ItemsSource="{Binding Path=DataGridSelectedYear, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" 
                  Margin="0,55,0,0">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <uc:DataGrid Height="160" Width="300" 
                             HorizontalAlignment="Center"
                             VerticalAlignment="Center"
                             DataGridSource="{Binding}"
                             Tag="{Binding RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
                             SelectedCells="{Binding DataContext.TestList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType=Window}}"
                             Margin="20,20,0,0">
                    <uc:DataGrid.ContextMenu>
                        <ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
                            <MenuItem Header="Test" 
                                      Command="{Binding Path=DataContext.AddBackColorCommand}"
                                      CommandParameter="{Binding}"
                                      />
                        </ContextMenu>
                    </uc:DataGrid.ContextMenu>
                </uc:DataGrid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

但如果我将该属性添加到Itemscontrol从其中获取数据的类(DataGridSelectedYear)中,它也不起作用。调试器中也没有绑定错误,但setter从未被调用。

0x6upsns

0x6upsns1#

绑定引擎在设置依赖项属性时调用DependencyObjectSetValue方法,因此在绑定到源属性时不应调用SelectedCells属性的setter。
如果要确认属性是否按预期设置,可以注册PropertyChangedCallback

相关问题