WPF DataGrid在同一列中的不同控件 - 不正确的绑定

时间:2015-05-06 14:51:24

标签: c# wpf xaml datagrid

我正在开发对项目列表执行检查的应用程序。每个项目都有需要对其执行的检查列表。每个检查可以是3种类型之一:CheckBox,ComboBox,TextBox。

我想让Datagrid有2列(一个用于项目名称,第二列用于检查列表)。第二列包含另一个具有2列的DataGrid(一列用于检查名称,第二列用于检查控制)。目的是在与Check模型绑定的同一列中使用不同类型的控件。

问题是与CheckValue的绑定不起作用,但是与所有其他属性的绑定工作正常。

最后一列包含CheckBoxes,TextBox和ComboBox,但它们没有填充任何值。 有谁知道下面的代码有什么问题?

以下是模型类的示例

public class Item
{
    public string ItemName { get; set; }
    public ObservableCollection<Check> Checks { get; set; }

    public Item()
    {
        Checks = new ObservableCollection<Check>();
    }
}

public enum CheckType
{
    CheckBox,
    ComboBox,
    TextBox
}

public abstract class Check
{        
    public string CheckName { get; set; }
    public CheckType CheckType { get; protected set; }
    public abstract object CheckValue { get; set; }
}

public class CheckBox : Check
{
    private bool checkValue;

    public CheckBox()
    {
        CheckType = CheckType.CheckBox;
    }

    public override object CheckValue
    {
        get
        {
            return checkValue;
        }
        set
        {
            checkValue = (bool)value;
        }
    }
}

public class ComboBox : Check
{
    private List<string> checkValue;

    public ComboBox()
    {
        CheckType = CheckType.ComboBox;
    }

    public override object CheckValue
    {
        get
        {
            return checkValue;
        }
        set
        {
            checkValue = value as List<string>;
        }
    }
}

public class TextBox : Check
{
    private string checkValue;

    public TextBox()
    {
        CheckType = CheckType.TextBox;
    }

    public override object CheckValue
    {
        get
        {
            return checkValue;
        }
        set
        {
            checkValue = value as string;
        }
    }
}

public class MainViewModel
{
    public ObservableCollection<Item> Items { get; set; }

    public MainViewModel()
    {
        Items = new ObservableCollection<Item>();

        Item item = new Item();
        item.ItemName = "First item";

        Check check1 = new CheckBox() { CheckName = "Check 1", CheckValue = true };
        Check check2 = new CheckBox() { CheckName = "Check 2", CheckValue = false };
        Check text1 = new TextBox() { CheckName = "Check 3", CheckValue = "Please enter check" };
        Check combo1 = new ComboBox() { CheckName = "Check 4", CheckValue = new List<string> { "Value1", "Value2" } };

        item.Checks.Add(check1);
        item.Checks.Add(check2);
        item.Checks.Add(text1);
        item.Checks.Add(combo1);

        Items.Add(item);
    }
}

最后这里是主窗口的XAML代码。

<Window x:Class="ItemTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm ="clr-namespace:ItemTest"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <vm:MainViewModel x:Key="mainViewModel"/>         
</Window.Resources>

<Grid DataContext="{Binding Source={StaticResource mainViewModel}}">
    <DataGrid ItemsSource="{Binding Path=Items}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Item" Binding="{Binding ItemName}" /> 
            <DataGridTemplateColumn Header="Checks">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <DataGrid ItemsSource="{Binding Checks}" AutoGenerateColumns="False" HeadersVisibility="None">
                            <DataGrid.Columns>
                                <DataGridTextColumn Binding="{Binding CheckName}" />
                                <DataGridTemplateColumn>
                                    <DataGridTemplateColumn.CellTemplate>
                                        <DataTemplate>
                                            <ContentControl>
                                                <ContentControl.Style>
                                                    <Style TargetType="ContentControl">
                                                        <Style.Triggers>
                                                            <DataTrigger Binding="{Binding CheckType}" Value="CheckBox">
                                                                <Setter Property="ContentTemplate">
                                                                    <Setter.Value>
                                                                        <DataTemplate>
                                                                            <CheckBox IsChecked="{Binding CheckValue}"/>
                                                                        </DataTemplate>
                                                                    </Setter.Value>
                                                                </Setter>
                                                            </DataTrigger>
                                                            <DataTrigger Binding="{Binding CheckType}" Value="ComboBox">
                                                                <Setter Property="ContentTemplate">
                                                                    <Setter.Value>
                                                                        <DataTemplate>
                                                                            <ComboBox ItemsSource="{Binding CheckValue}" />
                                                                        </DataTemplate>
                                                                    </Setter.Value>
                                                                </Setter>
                                                            </DataTrigger>
                                                            <DataTrigger Binding="{Binding CheckType}" Value="TextBox">
                                                                <Setter Property="ContentTemplate">
                                                                    <Setter.Value>
                                                                        <DataTemplate>
                                                                            <TextBox Text="{Binding CheckValue}" />
                                                                        </DataTemplate>
                                                                    </Setter.Value>
                                                                </Setter>
                                                            </DataTrigger>
                                                        </Style.Triggers>
                                                    </Style>
                                                </ContentControl.Style>
                                            </ContentControl>
                                        </DataTemplate>
                                    </DataGridTemplateColumn.CellTemplate>
                                </DataGridTemplateColumn>
                            </DataGrid.Columns>
                        </DataGrid>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

2 个答案:

答案 0 :(得分:1)

只需设置ItemControl的Content属性:

<ContentControl Content="{Binding}">

WPF会自动将DataTemplate的DataContext设置为其父ContentControl的内容。但是在你的XAML中你不设置Content属性(你只指定ContentControl的Style,但忘记设置它的内容)。

并且不要忘记在控件绑定上设置UpdateSourceTrigger=PropertyChanged,否则您可能会在视图模型中看不到更新。

答案 1 :(得分:0)

XAML示例正常工作,并且具有BindingList的绑定:

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    ...

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
          new TestBridgePackage()
      );
    }

    ...
  };

  ...
}