【发布时间】:2020-08-15 11:05:02
【问题描述】:
我已经搜索过很多地方。我的问题是,我无法找到解决我这个非常简单的问题的方法。 我有一个页面,它承载一个数据网格。目标是让数据网格中的名称在双击时可编辑。从数据库中检索数据。我只想在编辑过程完成而不是在“PropertyChanged”上更新“名称”属性。
我的自定义控件:
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace Ey.Ventuz.SessionManager.Ui
{
/// <summary>
/// Interaktionslogik für TextEditInPlace.xaml
/// </summary>
public partial class TextEditInPlace : UserControl, INotifyPropertyChanged
{
#region INotify
public event PropertyChangedEventHandler PropertyChanged;
public event EventHandler<string> NameChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
private bool isEditing;
/// <summary>
/// Is true while editing
/// </summary>
public bool IsEditing
{
get { return isEditing; }
set
{
isEditing = value;
OnPropertyChanged(nameof(IsEditing));
if(isEditing == false)
{
NameChanged?.Invoke(this, EditableText);
}
}
}
public string EditableText
{
get { return (string)GetValue(EditableTextProperty); }
set { SetValue(EditableTextProperty, value); }
}
// Using a DependencyProperty as the backing store for EditableText. This enables animation, styling, binding, etc...
public static readonly DependencyProperty EditableTextProperty =
DependencyProperty.Register("EditableText", typeof(string), typeof(TextEditInPlace), new PropertyMetadata("test"));
public TextEditInPlace()
{
InitializeComponent();
}
private void TextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount == 2)
{
IsEditing = true;
}
}
private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
IsEditing = false;
}
}
private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
IsEditing = false;
}
}
}
我的数据网格:
<DataGrid Name="myDataGrid"
ItemsSource="{Binding ItemList, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedStyle}"
RowHeaderWidth="100"
AutoGenerateColumns="False"
HorizontalAlignment="Stretch"
HeadersVisibility="Column"
SelectionMode="Single"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Thumbnail" Width="120">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding Path=Logo}"
Width="100"
Stretch="Uniform"
HorizontalAlignment="Left"
Margin="3"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Name" Width="120">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<local:TextEditInPlace EditableText="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="NameChanged">
<i:InvokeCommandAction Command="{Binding UpdateListItemNameCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</local:TextEditInPlace>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Binding="{Binding Path=Created, StringFormat=\{0:dd.MM.yyyy \}}" Header="Date" Width="*"/>
<DataGridTextColumn Binding="{Binding Path=CreatedBy}" Header="Author" Width="*"/>
</DataGrid.Columns>
</DataGrid>
我的视图模型:
using Ey.Ventuz.SessionManager.Data;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Data;
using System.Windows.Input;
namespace Ey.Ventuz.SessionManager.Ui
{
public class StyleConfigurationViewModel : BaseViewModel
{
public List<VentuzStyle> ventuzStyles;
public ICollectionView ItemList { get; set; }
public DefaultStyleData StyleData { get; set; }
private VentuzStyle selectedStyle;
public VentuzStyle SelectedStyle
{
get { return selectedStyle; }
set
{
if (value != null)
{
selectedStyle = value;
}
}
}
public ICommand UpdateListItemNameCommand { get; set; }
public ICommand GoBackCommand { get; set; }
public ICommand DuplicateStyleCommand { get; set; }
public ICommand RemoveStyleCommand { get; set; }
public StyleConfigurationViewModel()
{
InitializeProperties();
FillList();
GoBackCommand = new RelayCommand(() => GoBack());
DuplicateStyleCommand = new RelayCommand(() => DuplicateStyle());
RemoveStyleCommand = new RelayCommand(() => RemoveStyle());
UpdateListItemNameCommand = new RelayCommand(() => UpdateListItemName());
}
private void UpdateListItemName()
{
}
private void InitializeProperties()
{
ventuzStyles = new List<VentuzStyle>(SessionSelectionData.GetVentuzStyles());
if (ventuzStyles != null && ventuzStyles.Count > 0)
{
try
{
foreach (VentuzStyle ventuzStyle in ventuzStyles)
{
ventuzStyle.PropertyChanged += VentuzStyle_PropertyChanged;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
private void VentuzStyle_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
}
private void FillList()
{
ItemList = new CollectionViewSource() { Source = ventuzStyles }.View;
}
private void GoBack()
{
AggregatorLight.GoBack("go back");
}
private void DuplicateStyle()
{
VentuzStyle _ventuzStyle = new VentuzStyle();
_ventuzStyle = ObjectCopier.DeepCopy(SelectedStyle);
ventuzStyles.Add(SessionSelectionData.CreateStyle(_ventuzStyle));
ItemList.Refresh();
}
private void RemoveStyle()
{
if(ventuzStyles.Count() > 0)
{
SessionSelectionData.RemoveStyle(SelectedStyle);
ventuzStyles.Remove(SelectedStyle);
}
ItemList.Refresh();
}
}
}
如何在自定义用户控件中创建自定义事件?如何在 XAML 中使用它?我对任何 cmets 都很满意。
非常感谢
更新:这是 TextEditInPlace 的 Xaml:
<Grid Height="Auto" Width="Auto">
<TextBlock Text="{Binding EditableText, ElementName=userControl}"
Visibility="{Binding IsEditing, ElementName=userControl, Converter={local:BooleanToInvisibilityConverter}}"
MouseLeftButtonDown="TextBlock_MouseLeftButtonDown" />
<TextBox Text="{Binding EditableText, ElementName=userControl, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Visibility="{Binding IsEditing, ElementName=userControl, Converter={local:BooleanToVisibilityConverter}}"
Style="{StaticResource TextEditBox}" Margin="-4"
KeyDown="TextBox_KeyDown"
LostFocus="TextBox_LostFocus" />
</Grid>
【问题讨论】: