在 WPF 中,我无法通过两种方式绑定到 DataGrid 以供用户控制到 Observable 集合

In WPF I can't get the two way binding to work on DataGrid for User Control to Observable collection

我有一个自定义 UserControl,它被修改为具有 3 个状态。它与我自己的用户控件的依赖项 属性 和具有 ObservableCollection 数据的 Tag 属性 绑定到 DataGrid。我不知道为什么我的数据在更改时没有更新。我将它设置为双向绑定。我正在使用 ItemCollectionViewSource 进行数据绑定。这是我的代码。

My DataGrid

<DataGrid x:Name="datagrdControlListGrid" AutoGenerateColumns="False" Margin="0" CanUserSortColumns="False"  AlternatingRowBackground="Gainsboro"  AlternationCount="2" DataContext="{StaticResource ItemCollectionViewSource}" ItemsSource="{Binding ''}" MinColumnWidth="50" GridLinesVisibility="None">
            <DataGrid.Columns>

                <DataGridTemplateColumn Header="Join"  Width="SizeToCells" IsReadOnly="False" CanUserSort="True" SortDirection="Ascending">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Width="auto" Text="{Binding JoinNum, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <DataGridTemplateColumn Header="Control Name" Width="SizeToCells" CanUserSort="True"  SortDirection="Descending" >
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Width="auto" Text="{Binding ControlName, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <DataGridTemplateColumn Header="Type" Width="SizeToCells" CanUserSort="True" >
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Width="auto" Text="{Binding ControlType, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <DataGridTemplateColumn Header="Description" Width="SizeToCells" >
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Width="auto" Text="{Binding ControlDesc, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <DataGridTemplateColumn Header="Result" Width="SizeToCells" >
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <!--<CheckBox  IsThreeState="True" Width="20" Height="20" />-->
                            <Grid  Height="32"  Width="85">
                                <UserControls:FancyButton Width="82" Tag="{Binding Result , Mode=TwoWay}" 
                                                          ButtonState="{Binding Result, Mode=TwoWay }" Height="35" />
                            </Grid>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <DataGridTemplateColumn Header="Comment" Width="SizeToCells" >
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Width="170" Text="{Binding Comment, Mode=TwoWay,  UpdateSourceTrigger=LostFocus}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

            </DataGrid.Columns>
        </DataGrid>

Here is my usercontrol XAML

<UserControl x:Class="caM.UserControls.FancyButton"
         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" 
         xmlns:local="clr-namespace:caM.UserControls"
         mc:Ignorable="d" Width="37" Height="31">
<UserControl.Resources>

</UserControl.Resources>
<Grid>
    <Button x:Name="HelloButton" Click="Button_Click"  Tag="{Binding Path= ButtonState , Mode=TwoWay ,UpdateSourceTrigger=PropertyChanged}" Margin="0" LostFocus="HelloButton_LostFocus">
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Style.Triggers>
                    <Trigger Property="Tag" Value="None">
                        <Setter Property="Content" Value="Image1"/>
                        <Setter Property="Content">
                            <Setter.Value>
                                <Grid>
                                    <Rectangle Width="Auto" Height="Auto" Tag="None" RadiusY="18" RadiusX="18">
                                        <Rectangle.Fill>
                                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                                <GradientStop Color="#FFBBBBBB" Offset="0.004"/>
                                                <GradientStop Color="#FFBBBBBB" Offset="0.992"/>
                                                <GradientStop Color="#FFEEEEEE" Offset="0.209"/>
                                                <GradientStop Color="#FFEAEAEA" Offset="0.771"/>
                                                <GradientStop Color="White" Offset="0.478"/>
                                            </LinearGradientBrush>
                                        </Rectangle.Fill>
                                    </Rectangle>
                                </Grid>

                            </Setter.Value>
                        </Setter>
                    </Trigger>
                    <Trigger Property="Tag" Value="On">
                        <Setter Property="Content" Value="Image2"/>
                        <Setter Property="Content">
                            <Setter.Value>
                                <Grid>
                                    <Rectangle Width="Auto" Height="Auto" Tag="None" RadiusY="18" RadiusX="18">
                                        <Rectangle.Fill>
                                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                                <GradientStop Color="#FF2A9C25" Offset="0.004"/>
                                                <GradientStop Color="#FF2A9C25" Offset="0.992"/>
                                                <GradientStop Color="#FF8DE28D" Offset="0.209"/>
                                                <GradientStop Color="#FFA3E6A0" Offset="0.763"/>
                                                <GradientStop Color="#FFC9FFC6" Offset="0.482"/>
                                            </LinearGradientBrush>
                                        </Rectangle.Fill>
                                    </Rectangle>
                                </Grid>

                            </Setter.Value>
                        </Setter>
                    </Trigger>
                    <Trigger Property="Tag" Value="Off">
                        <Setter Property="Content" Value="Image3"/>
                        <Setter Property="Content">
                            <Setter.Value>
                                <Grid>
                                    <Rectangle Width="Auto" Height="Auto" Tag="None" RadiusY="18" RadiusX="18">
                                        <Rectangle.Fill>
                                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                                <GradientStop Color="#FF9C2525" Offset="0.004"/>
                                                <GradientStop Color="#FF9C2525" Offset="0.992"/>
                                                <GradientStop Color="#FFE28D8D" Offset="0.209"/>
                                                <GradientStop Color="#FFE6A0A0" Offset="0.763"/>
                                                <GradientStop Color="#FFFFC6C6" Offset="0.482"/>
                                            </LinearGradientBrush>
                                        </Rectangle.Fill>
                                    </Rectangle>
                                </Grid>

                            </Setter.Value>
                        </Setter>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
        <Button.Template>
            <ControlTemplate TargetType="{x:Type Button}">

                <Grid>
                    <Rectangle Width="Auto" Height="Auto" Tag="None" RadiusY="18" RadiusX="18">
                        <Rectangle.Fill>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <GradientStop Color="#FFBBBBBB" Offset="0.004"/>
                                <GradientStop Color="#FFBBBBBB" Offset="0.992"/>
                                <GradientStop Color="#FFEEEEEE" Offset="0.209"/>
                                <GradientStop Color="#FFEAEAEA" Offset="0.771"/>
                                <GradientStop Color="White" Offset="0.478"/>
                            </LinearGradientBrush>
                        </Rectangle.Fill>
                    </Rectangle>
                    <ContentPresenter Content="{TemplateBinding Content}"/>
                </Grid>
            </ControlTemplate>
        </Button.Template>
    </Button>

</Grid>

Here is my UserControl.xaml.cs

public partial class FancyButton : UserControl
    {
        public FancyButton()
        {
            InitializeComponent();
            this.DataContext = this;
            Tag = "None";
            ButtonState = "None";
        }



        public string ButtonState 
        {
            get { return (string)GetValue(ButtonStateProperty); }
            set { SetValue(ButtonStateProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ButtonState.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ButtonStateProperty =
            DependencyProperty.Register("ButtonState", typeof(string), typeof(FancyButton), new PropertyMetadata(""));




        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var roaw = ((FrameworkElement)sender).DataContext as DataRowView;


            if (HelloButton.Tag.ToString() == "None")
            {
                HelloButton.Tag = "On";
                ButtonState = "On";
            }
            else if (HelloButton.Tag.ToString() == "On")
            {
                HelloButton.Tag = "Off";
                ButtonState = "Off";
            }
            else if (HelloButton.Tag.ToString() == "Off")
            {
                HelloButton.Tag = "None";
                ButtonState = "None";
            }
            else
            {
                HelloButton.Tag = "On";
                ButtonState = "On";
            }
        }

        private void HelloButton_LostFocus(object sender, RoutedEventArgs e)
        {

        }
    }

如果您定义了自己的自定义 ButtonState 属性,则不需要使用 Tag 属性。此外,您正在覆盖 UserControl 的 DataContext。不要这样做。此代码应该可以更好地工作:

public partial class FancyButton : UserControl
{
    public FancyButton()
    {
        InitializeComponent();
    }

    public string ButtonState
    {
        get { return (string)GetValue(ButtonStateProperty); }
        set { SetValue(ButtonStateProperty, value); }
    }

    public static readonly DependencyProperty ButtonStateProperty =
        DependencyProperty.Register("ButtonState", typeof(string), typeof(FancyButton), new PropertyMetadata(""));

    private void Button_Click(object sender, RoutedEventArgs e)
    {

        if (ButtonState == "None")
        {
            ButtonState = "On";
        }
        else if (ButtonState == "On")
        {
            ButtonState = "Off";
        }
        else if (ButtonState == "Off")
        {
            ButtonState = "None";
        }
        else
        {
            ButtonState = "On";
        }
    }

    private void HelloButton_LostFocus(object sender, RoutedEventArgs e)
    {

    }
}

XAML:

<Button x:Name="HelloButton" Click="Button_Click" Margin="0" LostFocus="HelloButton_LostFocus">
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding ButtonState, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="None">
                    <Setter Property="Content" Value="Image1"/>
                    <Setter Property="Content">
                        <Setter.Value>
                            <Grid>
                                <Rectangle Width="Auto" Height="Auto" Tag="None" RadiusY="18" RadiusX="18">
                                    <Rectangle.Fill>
                                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                            <GradientStop Color="#FFBBBBBB" Offset="0.004"/>
                                            <GradientStop Color="#FFBBBBBB" Offset="0.992"/>
                                            <GradientStop Color="#FFEEEEEE" Offset="0.209"/>
                                            <GradientStop Color="#FFEAEAEA" Offset="0.771"/>
                                            <GradientStop Color="White" Offset="0.478"/>
                                        </LinearGradientBrush>
                                    </Rectangle.Fill>
                                </Rectangle>
                            </Grid>

                        </Setter.Value>
                    </Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding ButtonState, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="On">
                    <Setter Property="Content" Value="Image2"/>
                    <Setter Property="Content">
                        <Setter.Value>
                            <Grid>
                                <Rectangle Width="Auto" Height="Auto" Tag="None" RadiusY="18" RadiusX="18">
                                    <Rectangle.Fill>
                                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                            <GradientStop Color="#FF2A9C25" Offset="0.004"/>
                                            <GradientStop Color="#FF2A9C25" Offset="0.992"/>
                                            <GradientStop Color="#FF8DE28D" Offset="0.209"/>
                                            <GradientStop Color="#FFA3E6A0" Offset="0.763"/>
                                            <GradientStop Color="#FFC9FFC6" Offset="0.482"/>
                                        </LinearGradientBrush>
                                    </Rectangle.Fill>
                                </Rectangle>
                            </Grid>

                        </Setter.Value>
                    </Setter>
                </DataTrigger>
                <DataTrigger Binding="{Binding ButtonState, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="Off">
                    <Setter Property="Content" Value="Image3"/>
                    <Setter Property="Content">
                        <Setter.Value>
                            <Grid>
                                <Rectangle Width="Auto" Height="Auto" Tag="None" RadiusY="18" RadiusX="18">
                                    <Rectangle.Fill>
                                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                            <GradientStop Color="#FF9C2525" Offset="0.004"/>
                                            <GradientStop Color="#FF9C2525" Offset="0.992"/>
                                            <GradientStop Color="#FFE28D8D" Offset="0.209"/>
                                            <GradientStop Color="#FFE6A0A0" Offset="0.763"/>
                                            <GradientStop Color="#FFFFC6C6" Offset="0.482"/>
                                        </LinearGradientBrush>
                                    </Rectangle.Fill>
                                </Rectangle>
                            </Grid>

                        </Setter.Value>
                    </Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
    <Button.Template>
        <ControlTemplate TargetType="{x:Type Button}">
            <Grid>
                <Rectangle Width="50" Height="50" Tag="None" RadiusY="18" RadiusX="18">
                    <Rectangle.Fill>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="#FFBBBBBB" Offset="0.004"/>
                            <GradientStop Color="#FFBBBBBB" Offset="0.992"/>
                            <GradientStop Color="#FFEEEEEE" Offset="0.209"/>
                            <GradientStop Color="#FFEAEAEA" Offset="0.771"/>
                            <GradientStop Color="White" Offset="0.478"/>
                        </LinearGradientBrush>
                    </Rectangle.Fill>
                </Rectangle>
                <ContentPresenter Content="{TemplateBinding Content}"/>
            </Grid>
        </ControlTemplate>
    </Button.Template>
</Button>