- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
假设我有一个像这样的组合框:
<ComboBox SelectedValue="{Binding DataContext.CanUserAddMultipleRows,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}},
Converter={StaticResource yesNoToBooleanConverter}}">
<ComboBoxItem>Yes</ComboBoxItem>
<ComboBoxItem>No</ComboBoxItem>
</ComboBox>
这是转换器:
public class YesNoToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (!(value == null || value == DependencyProperty.UnsetValue))
{
if ((bool)value == true)
{
return "Yes";
}
else
{
return "No";
}
}
else
{
return "No";
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (!(value == null || value == DependencyProperty.UnsetValue))
{
if (((ComboBoxItem)value).Content.ToString() == "Yes")
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
}
现在我有一个数据网格:
<DataGrid Grid.Row="7" Grid.Column="1" Grid.ColumnSpan="2" AutoGenerateColumns="False"
CanUserAddRows="{Binding DataContext.CanUserAddMultipleRows,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}}}"
ItemsSource="{Binding DataContext.MyObject,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}}}">
<DataGrid.Columns>
<DataGridTextColumn Header="Quantity" Binding="{Binding Quantity}"></DataGridTextColumn>
<DataGridTextColumn Header="Rate" Binding="{Binding Rate}"></DataGridTextColumn>
<DataGridTextColumn Header="Amount" Binding="{Binding Amount}"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
现在我想默认为用户提供 1 行,这样如果 CanUserAddRows = false,那么他们也应该能够向 DataGrid 添加 1 项。如果 CanUserAddRows = true,则用户可以拥有他想要的任意数量的行。
这件事可能很简单,但我是 DataGrid 的新手。所以,我问了这个问题。
最佳答案
在我的示例中,有一个bool 类型的MayUserAddRows
属性。如果 MayUserAddRows == true
那么用户可以添加任意多条记录,但是如果 MayUserAddRows == false
那么他只能填写一条记录。
还有CanUserAddRows
属性,直接绑定(bind)DataGrid.CanUserAddRows
属性。
ViewModel 中的属性实现了 INotifyPropertyChanged
通过 NotificationObject 接口(interface)。他有一个事件 PropertyChangedEventHandler(propertyName)
通知通知属性。关键逻辑在这里:
private void MyViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName.Equals("MayUserAddRows"))
{
// The MayUserAddRows property is changed
if (MyViewModel.MayUserAddRows == true)
{
// Allow to add a lot of records
MyViewModel.CanUserAddRows = true;
}
if (MyViewModel.MayUserAddRows == false)
{
// Prohibit the addition
MyViewModel.CanUserAddRows = false;
// And add the empty row
AddEmptyRow(MyViewModel.MyCollection);
}
}
}
下面是一个完整的例子:
XAML
<Window x:Class="ConditionalCanUserAddRows.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:this="clr-namespace:ConditionalCanUserAddRows"
WindowStartupLocation="CenterScreen"
Title="MainWindow" Height="300" Width="325">
<Grid>
<CheckBox Content="{Binding Path=IsChecked,
RelativeSource={RelativeSource Mode=Self}}"
ContentStringFormat="May user add rows - {0}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
IsChecked="{Binding Path=MayUserAddRows}" />
<Button Content="Clear"
VerticalAlignment="Top"
HorizontalAlignment="Right"
Click="Clear_Click" />
<DataGrid Name="SimpleDataGrid"
Width="200"
Height="200"
CanUserResizeColumns="False"
AutoGenerateColumns="False"
RowHeaderWidth="0"
CanUserAddRows="{Binding Path=CanUserAddRows, Mode=TwoWay}"
ItemsSource="{Binding Path=MyCollection}">
<DataGrid.Columns>
<DataGridTextColumn Width="1.5*"
Header="Name"
Binding="{Binding Path=Name}" />
<DataGridTextColumn Header="Age"
Width="1.5*"
FontSize="14"
Binding="{Binding Path=Age}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
代码隐藏
public partial class MainWindow : Window
{
ViewModel MyViewModel = new ViewModel();
public MainWindow()
{
InitializeComponent();
this.DataContext = MyViewModel;
MyViewModel.MyCollection = new ObservableCollection<Person>();
MyViewModel.MyCollection.Add(new Person()
{
Age = 22,
Name = "Nick",
});
MyViewModel.MyCollection.Add(new Person()
{
Age = 11,
Name = "Sam",
});
MyViewModel.MyCollection.Add(new Person()
{
Name = "Kate",
Age = 15,
});
AddEmptyRow(MyViewModel.MyCollection);
MyViewModel.PropertyChanged += new PropertyChangedEventHandler(MyViewModel_PropertyChanged);
}
private void MyViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName.Equals("MayUserAddRows"))
{
if (MyViewModel.MayUserAddRows == true)
{
MyViewModel.CanUserAddRows = true;
}
if (MyViewModel.MayUserAddRows == false)
{
MyViewModel.CanUserAddRows = false;
AddEmptyRow(MyViewModel.MyCollection);
}
}
}
#region AddEmptyRow
private void AddEmptyRow(ObservableCollection<Person> collection)
{
collection.Add(new Person()
{
Name = "",
Age = 0,
});
}
#endregion
#region Clear
private void Clear_Click(object sender, RoutedEventArgs e)
{
MyViewModel.MyCollection.Clear();
}
#endregion
}
#region ViewModel
public class ViewModel : NotificationObject
{
#region MyCollection
public ObservableCollection<Person> MyCollection
{
get;
set;
}
#endregion
#region CanUserAddRows
private bool _canUserAddRows = false;
public bool CanUserAddRows
{
get
{
return _canUserAddRows;
}
set
{
_canUserAddRows = value;
NotifyPropertyChanged("CanUserAddRows");
}
}
#endregion
#region MayUserAddRows
private bool _mayUserAddRows = false;
public bool MayUserAddRows
{
get
{
return _mayUserAddRows;
}
set
{
_mayUserAddRows = value;
NotifyPropertyChanged("MayUserAddRows");
}
}
#endregion
}
#endregion
#region Model
public class Person
{
public string Name
{
get;
set;
}
public int Age
{
get;
set;
}
}
#endregion
#region NotificationObject
public class NotificationObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
#endregion
输出
MayUserAddRows="False"
MayUserAddRows="True"
项目在Visual Studio 2010下编译,本例完全符合MVVM风格。
This project available
here
关于c# - WPF 中 DataGrid 中的条件 CanUserAddRows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22871082/
我想使用 DataGrid.CanUserAddRows = true 功能。不幸的是,它似乎仅适用于具有默认构造函数的具体类。我的业务对象集合没有提供默认的构造函数。 我正在寻找一种注册工厂的方法,
我有以下数据网格:
我需要在 DataGrid 中为 CanUserAddRows 设置一个行的样式。ItemsSource 用于 DataGrid 我使用 DataTable.DefaultView我试试:
假设我有一个像这样的组合框: Yes No 这是转换器: public class YesNoToBooleanConverter : IValueConverter {
我最近一直在研究 MVVM,在我发现 Caliburn.Micro 之后事情进展顺利;我仍处于早期学习阶段,但我相信我对 MVVM 基础知识感觉还不错。 我遇到了 WPF DataGrid 的问题,
我是一名优秀的程序员,十分优秀!