如何在xaml中绑定用户控件
本文关键字:绑定 用户 控件 xaml | 更新日期: 2023-09-27 18:22:49
我有一个包含数据网格和"过滤器面板"的MainWindow。过滤器面板可以通过用户输入(点击按钮)进行更改。我试图通过数据绑定来实现它。Im面临的问题是过滤器面板(它是一个用户控件)没有加载或刷新。
主窗口xaml:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250*" />
<ColumnDefinition Width="253*" />
</Grid.ColumnDefinitions>
<DataGrid AutoGenerateColumns="True" Height="200" HorizontalAlignment="Left" Margin="23,28,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="200" ItemsSource="{Binding OverviewableItems}" />
<UserControl Grid.Column="1" Content="{Binding UserControl}" DataContext="{Binding}" Grid.ColumnSpan="2" />
<Button Content="PersonFilter" Height="23" HorizontalAlignment="Left" Margin="23,268,0,0" Name="buttonPersonFilter" VerticalAlignment="Top" Width="75" Click="buttonPersonFilter_Click" />
<Button Content="ProjectFilter" Height="23" HorizontalAlignment="Left" Margin="132,268,0,0" Name="buttonProjectFilter" VerticalAlignment="Top" Width="75" Click="buttonProjectFilter_Click" />
</Grid>
代码背后:
private ViewModel _viewModel;
public MainWindow()
{
_viewModel = new ViewModel(new DataProvider());
DataContext = _viewModel;
_viewModel.PropertyChanged += _viewModel.SetFilterType;
InitializeComponent();
}
private void buttonProjectFilter_Click(object sender, RoutedEventArgs e)
{
_viewModel.OverviewType = OverviewType.Project;
}
private void buttonPersonFilter_Click(object sender, RoutedEventArgs e)
{
_viewModel.OverviewType = OverviewType.Person;
}
第一个用户控制:
<Grid>
<DatePicker Grid.Column="1" Grid.Row="1" Height="25" HorizontalAlignment="Left" Margin="19,18,0,0" Name="datePickerFundingTo" VerticalAlignment="Top" Width="115" Text="{Binding ElementName=ProjectFilter, Path=FundingTo}" />
</Grid>
这个用户控件的代码只有这个:
public DateTime FundingTo { get; set; }
public ProjectFilter()
{
FundingTo = DateTime.Now;
InitializeComponent();
}
其他用户控件:只包含一个TextBox和一个Button,为了简单起见,我没有添加任何代码
主窗口的ViewModel:
public class ViewModel : INotifyPropertyChanged
{
private UserControl _userControl;
public UserControl UserControl
{
get { return _userControl; }
set
{
if (_userControl == value)
{
return;
}
OnPropertyChanged("UserControl");
_userControl = value;
}
}
private OverviewType _overviewType = OverviewType.None;
public OverviewType OverviewType
{
get { return _overviewType; }
set
{
if (_overviewType == value)
{
return;
}
OnPropertyChanged("OverviewType");
_overviewType = value;
}
}
private ObservableCollection<IOverviewItem> _overviewableItems;
public ObservableCollection<IOverviewItem> OverviewableItems
{
get { return _overviewableItems; }
set
{
if (_overviewableItems == value)
{
return;
}
_overviewableItems = value;
}
}
private readonly DataProvider _dataProvider;
public event PropertyChangedEventHandler PropertyChanged;
public ViewModel(DataProvider dataProvider)
{
_dataProvider = dataProvider;
}
public void SetFilterType(object sender, EventArgs eventArgs)
{
switch (_overviewType)
{
case OverviewType.Project:
_userControl = new ProjectFilter();
break;
case OverviewType.Person:
_userControl = new PersonFilter();
break;
}
}
public void OnPropertyChanged(string name)
{
if (PropertyChanged == null)
return;
var eventArgs = new PropertyChangedEventArgs(name);
PropertyChanged(this, eventArgs);
}
}
另外,我有一个枚举OverviewType,值为None、Project、Person。
属性更改事件已正确激发,但用户控件未刷新。有人能告诉我,我的解决方案中的缺陷在哪里?
我还有一个问题,如何从用户控件到主窗口视图模型进行通信?外汇:数据网格应该根据其过滤器进行更改。
如有任何帮助,我们将不胜感激。干杯
这里有不同的问题。
-
正如Clemens所说,您必须在更新值后解雇您的活动。但这不是这里的主要问题。
-
第二个问题:您正在将您的新
usercontrol
影响到私人成员,因此您完全绕过了您的财产。
更换
_userControl = new ProjectFilter();
通过
this.UserControl = new ProjectFilter();
- 第三个问题,与您的问题没有直接关系,但实际上是您的最大问题:您有架构设计问题须不知道有关视图的任何信息,因此不得引用视图中的控件。您可以从视图模型中激发一个事件,并在视图中添加一个事件处理程序,而不是编写绑定,因此更新用户控件的是视图
在更改属性的后备字段后,尝试激发PropertyChanged
public UserControl UserControl
{
get { return _userControl; }
set
{
if (_userControl != value)
{
_userControl = value; // first
OnPropertyChanged("UserControl"); // second
}
}
}
类似于OverviewType
。