【发布时间】:2016-10-30 19:39:29
【问题描述】:
“编辑”
我想要达到的目标是 -
MainWindow.xaml 包含一个 Button、一个 ComboBox 和一个 ContentControl。 UserControl-A 和 UserControl-C 都包含一个 ContentControl。 UserControl-B 和 UserControl-D 都包含一个 TextBlock。
UserControl-B 将 ContentControl 的内容包含在 用户控制-A。 UserControl-D 将是 ContentControl 的内容 包含在 UserControl-C 中。
UserControl-A 或 UserControl-C 将是 ContentControl 的内容 单击按钮时包含在 MainWindow.xaml 中。
关于改变 Combobox 的 SelectedValue 更新 TextBlock 的 UserControl-B 或 UserControl-D。
“编辑”
除了 MainWindow.xaml、App.xaml 和 App.config 我还有 MainContent1.xaml、MainContent2.xaml、ComboItems.cs 和两个子文件夹 Sub1 和 Sub2,它们每个都包含一个名为 S1.xaml 的文件,在我的项目。
我所有的代码都写在 ComboItems.cs 作为 -
namespace MultiBinding
{
public class Item
{
public string Name { get; set; }
public int Id { get; set; }
}
public class ComboItems
{
public ComboItems()
{
Items = new List<Item>(3);
for (int i = 1; i < 4; i++)
Items.Add(new Item { Id = i, Name = "Name " + i });
}
public List<Item> Items { get; set; }
}
public class ButtonContent : INotifyPropertyChanged
{
public ICommand MyCommand { get; set; }
private string _content;
public ButtonContent()
{
_content = "First";
MyCommand = new Command(Do, CanDo);
}
public string Content
{
get { return _content; }
set { _content = value; OnChange("Content"); }
}
private bool CanDo(object parameter) => true;
private void Do(object parameter) => Content = Content == "First" ? "Second" : "First";
public event PropertyChangedEventHandler PropertyChanged;
private void OnChange(string name) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public class Command : ICommand
{
private Action<object> Do;
private Func<object, bool> CanDo;
public Command(Action<object> Do, Func<object, bool> CanDo)
{
this.Do = Do;
this.CanDo = CanDo;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter) => true;
public void Execute(object parameter) => Do(parameter);
}
public class SomeText
{
public static string Text1 { get; set; }
public static string Text2 { get; set; }
}
public class Converter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
switch (values[1].ToString())
{
case "1": SomeText.Text1 = SomeText.Text2 = "Selected Item is 1"; break;
case "2": SomeText.Text1 = SomeText.Text2 = "Selected Item is 2"; break;
case "3": SomeText.Text1 = SomeText.Text2 = "Selected Item is 3"; break;
}
if (values[0].ToString() == "First") return new MainContent1();
else return new MainContent2();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
MainWindow.xaml 的内容是 -
<Window x:Class="MultiBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MultiBinding">
<Window.Resources>
<local:ComboItems x:Key="cboItems" />
<local:Item x:Key="Item" />
<local:Converter x:Key="convert" />
<local:ButtonContent x:Key="content"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="10*"/>
<RowDefinition Height="90*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<ComboBox x:Name="combo"
DataContext="{Binding Source={StaticResource Item}}"
ItemsSource="{Binding Path=Items, Source={StaticResource cboItems}}"
DisplayMemberPath="Name"
SelectedValuePath="Id"
SelectedValue="{Binding Path=Id}"/>
<Button x:Name="butt" Grid.Column="1"
DataContext="{Binding Source={StaticResource content}}"
Content="{Binding Path=Content}"
Command="{Binding Path=MyCommand}"/>
<ContentControl Grid.Row="1" Grid.ColumnSpan="2">
<ContentControl.Content>
<MultiBinding Converter="{StaticResource convert}">
<Binding ElementName="butt" Path="Content"/>
<Binding ElementName="combo" Path="SelectedValue"/>
</MultiBinding>
</ContentControl.Content>
</ContentControl>
</Grid>
MainContent1.xaml 的内容是 -
<UserControl x:Class="MultiBinding.MainContent1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sub="clr-namespace:MultiBinding.Sub1">
<UserControl.Resources>
<sub:S1 x:Key="s1"/>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock FontSize="20" Text="On Main ContentControl No. 1"/>
<ContentControl
Content="{Binding Source={StaticResource s1}}"
Grid.Row="1"/>
</Grid>
MainContent2.xaml 包含与上面完全相同的代码,除了
xmlns:sub="clr-namespace:MultiBinding.Sub2"
文件夹 Sub1 下 S1.xaml 的内容是 -
<UserControl x:Class="MultiBinding.Sub1.S1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:main="clr-namespace:MultiBinding">
<UserControl.Resources>
<main:SomeText x:Key="MyText"/>
</UserControl.Resources>
<Grid Background="Bisque">
<TextBlock Text="{Binding Text1, Source={StaticResource MyText}}" />
</Grid>
文件夹 Sub2 下的 S1.xaml 与 Sub1 文件夹类似,但
<TextBlock Text="{Binding Path=Text2, Source={StaticResource MyText}}" />
以这种方式一切正常。
在 ComboItems.cs 中 SomeText 类的 Text1 和 Text2 属性前面使用 static 关键字是否有问题?
如何在不使用 SomeText 类的静态属性的情况下实现相同的功能?
【问题讨论】:
-
这需要大量的代码来理解你想要做什么。如果您将问题写在顶部并花一些时间减少源代码的数量,您可能会得到更好的帮助。 HTH
-
长问题,短答案 - 使用 MVVM 模式。您可以将不同的控件与通用数据模型链接
-
@benPearce 我的回答是否遵循 MVVM 模式?
标签: wpf