“EDIT”
我想要达到的目标是 -
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的内容 单击Button时包含在MainWindow.xaml中。
更改Combobox更新TextBlock的SelectedValue UserControl-B或UserControl-D。
“EDIT”
除了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属性的静态关键字infront是否有任何问题?
如何在不使用SomeText类的静态属性的情况下实现相同的功能?
答案 0 :(得分:0)
我从ComboItems.cs中删除了“ComboItems and Converter”类,将“ButtonContent”类重命名为“MyCode”并按如下方式实现 -
public class MyCode : INotifyPropertyChanged
{
//Fields
private Sub1.S1 _s1;
private Sub2.S1 _s2;
private MainContent1 _m1;
private MainContent2 _m2;
private object _mainContent;
private object _subContent;
private int _selectedIndex;
//Properties
public string Text { get; set; }
public List<Item> Items { get; set; }
public ICommand MyCommand { get; set; }
public string Content { get; set; }
public object MainContent
{
get { return _mainContent; }
set { _mainContent = value; OnChange("MainContent"); }
}
public object SubContent
{
get { return _subContent; }
set { _subContent = value; OnChange("SubContent"); }
}
public int SelectedIndex
{
get { return _selectedIndex; }
set
{
_selectedIndex = value;
//Action on selection change
switch (_selectedIndex)
{
case 0: Text = "Selected Item is 1"; break;
case 1: Text = "Selected Item is 2"; break;
case 2: Text = "Selected Item is 3"; break;
}
OnChange("Text");
}
}
//Constructor
public MyCode()
{
Content = "First";
MyCommand = new Command(Do, CanDo);
_m1 = new MainContent1();
_m2 = new MainContent2();
_s1 = new Sub1.S1();
_s2 = new Sub2.S1();
MainContent = _m1;
SubContent = _s1;
Items = new List<Item>(3);
for (int i = 1; i < 4; i++)
Items.Add(new Item { Id = i, Name = "Name " + i });
SelectedIndex = 0;
}
//Action on Button Click
private void Do(object parameter)
{
if(Content == "First")
{
MainContent = _m2;
SubContent = _s2;
Content = "Second";
}
else
{
MainContent = _m1;
SubContent = _s1;
Content = "First";
}
OnChange("Content");
}
private bool CanDo(object parameter) => true;
//Inotify
public event PropertyChangedEventHandler PropertyChanged;
private void OnChange(string name) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
将MainWindow.xaml更改为 -
<Window.Resources>
<local:MyCode x:Key="Code"/>
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource Code}}">
<Grid.RowDefinitions...>
<Grid.ColumnDefinitions...>
<ComboBox ItemsSource="{Binding Path=Items}"
DisplayMemberPath="Name"
SelectedValuePath="Id"
SelectedIndex="{Binding Path=SelectedIndex}"/>
<Button x:Name="butt" Grid.Column="1"
Content="{Binding Path=Content}"
Command="{Binding Path=MyCommand}"/>
<ContentControl Grid.Row="1" Grid.ColumnSpan="2"
Content="{Binding Path=MainContent}"/>
</Grid>
MainContent1.xaml和MainContent2.xaml现在都包含 -
<ContentControl Content="{Binding Path=SubContent}"/>
文件夹Sub1和Sub2下的S1.xaml包含 -
<TextBlock Text="{Binding Path=Text}" />
完成!