Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果条件得到验证,在单元格上显示组合框的最佳方式是什么?_C#_Wpf_Combobox - Fatal编程技术网

C# 如果条件得到验证,在单元格上显示组合框的最佳方式是什么?

C# 如果条件得到验证,在单元格上显示组合框的最佳方式是什么?,c#,wpf,combobox,C#,Wpf,Combobox,所以我的问题是:我必须在我的视图上构建一个网格(它可以是datagrid或gridview,我没有特别的偏好)。我知道列的数量,但我必须以友好的方式构建行。问题是,如果第一列中数据的数据类型不同于“字符串”,则某些行必须在第三列上显示组合框,否则它们会有一个简单的文本框。我知道有一个名为“template selector”的控件可以做类似的事情,但由于我从未使用过它,我想知道这是否是解决问题的最佳方法 在不了解任何有关您尝试执行的操作的详细信息的情况下,例如,您可以将DataGridTempl

所以我的问题是:我必须在我的视图上构建一个网格(它可以是datagrid或gridview,我没有特别的偏好)。我知道列的数量,但我必须以友好的方式构建行。问题是,如果第一列中数据的数据类型不同于“字符串”,则某些行必须在第三列上显示组合框,否则它们会有一个简单的文本框。我知道有一个名为“template selector”的控件可以做类似的事情,但由于我从未使用过它,我想知道这是否是解决问题的最佳方法

在不了解任何有关您尝试执行的操作的详细信息的情况下,例如,您可以将
DataGridTemplateColumn
CellTemplateSelector
/
CellEditingTemplateSelector
一起使用

下面的示例代码应该能让您了解这一点:

<DataGrid x:Name="dg">
    <DataGrid.Resources>
        <DataTemplate x:Key="dtA">...</DataTemplate>
        <DataTemplate x:Key="dtB">...</DataTemplate>
        <local:Selector x:Key="selector" TemplateA="{StaticResource dtA}" TemplateB="{StaticResource dtA}" />
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding A}" />
        <DataGridTextColumn Binding="{Binding B}" />
        <DataGridTemplateColumn CellEditingTemplateSelector="{StaticResource selector}">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding C}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

在评论之后,如果您愿意使用
ItemsControl
来代替网格,则实现所述行为的一种方法如下:

视图:


代码隐藏+视图模型:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new MainWindowViewModel();
    }
}

public class MainWindowViewModel
{
    public MainWindowViewModel()
    {
        MyItems = new List<DisplayableItem>
        {
            new DisplayableItem { FirstProperty = "Some string" },
            new DisplayableItem { FirstProperty = 60 },
            new DisplayableItem { FirstProperty = "Also a string" },
        };
    }

    public IEnumerable<DisplayableItem> MyItems { get; }
}

public class DisplayableItem
{
    public object FirstProperty { get; set; }
    public bool HasCombobox => !(FirstProperty is string);
}
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
DataContext=新的MainWindowViewModel();
}
}
公共类MainWindowViewModel
{
公共主窗口视图模型()
{
MyItems=新列表
{
新的DisplayableItem{FirstProperty=“Some string”},
新的可显示项{FirstProperty=60},
新的DisplayableItem{FirstProperty=“也是字符串”},
};
}
公共IEnumerable MyItems{get;}
}
公共类可显示项
{
公共对象FirstProperty{get;set;}
public bool HasCombobox=>!(FirstProperty是字符串);
}

根据我的经验,数据网格中的组合框很快就会变得挑剔。在任何情况下,一种可能的解决方案是将组合框的可见性(通过
BooleanToVisibilityConverter
)绑定到其
bool
getter仅返回
的属性!(itemInFirstColumn是字符串)
。这种方法一点也不错。只有一个问题,如果我将combobx的选择绑定到我的ViewModel,我对ItemControl的单向绑定模式有什么问题吗?没有任何您仍然无法绕过的问题;我想需要更多的细节来说明你想要做什么才能知道最优雅的方法是什么。我花了时间来测试你的解决方案,它非常适合满足我的需要。在开始定制此解决方案之前,我还有一个问题。有没有一种方法可以根据FirstProperty的数据类型为combobox提供不同的项目源?一种低调的解决方案是让绑定的
ItemsSource
本身在选中
FirstProperty
后返回相关集合。这会将选择逻辑放在视图模型而不是视图中,这可能会与应用程序的语义冲突,具体取决于您处理的数据类型。如果将逻辑完全放在视图中更有意义的话,您可以使用触发器设置所需的内容(?)我正在构建一个向导,在这一点上,我必须构建最后一个屏幕,它是前面每个部分的总和。因此,将逻辑放在视图模型中很好,因为组合框的选择是我输出的一部分。再次感谢你的帮助
<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BoolToVis"/>
</Window.Resources>
<StackPanel>
    <ItemsControl ItemsSource="{Binding MyItems, Mode=OneWay}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <Label Width="150" Content="{Binding FirstProperty}"/>
                    <ComboBox Width="150"
                              Visibility="{Binding HasCombobox, Converter={StaticResource BoolToVis}}"/>
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</StackPanel>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new MainWindowViewModel();
    }
}

public class MainWindowViewModel
{
    public MainWindowViewModel()
    {
        MyItems = new List<DisplayableItem>
        {
            new DisplayableItem { FirstProperty = "Some string" },
            new DisplayableItem { FirstProperty = 60 },
            new DisplayableItem { FirstProperty = "Also a string" },
        };
    }

    public IEnumerable<DisplayableItem> MyItems { get; }
}

public class DisplayableItem
{
    public object FirstProperty { get; set; }
    public bool HasCombobox => !(FirstProperty is string);
}